1use macroquad::prelude::*;
2
3mod parse;
4mod textures;
5mod types;
6
7use crate::textures::*;
8
9fn get_check(board: &Vec<Vec<types::Piece>>, current: &types::PieceColor) -> bool {
10 for (idx, _) in board.iter().enumerate() {
11 for (idx2, _) in board[idx].iter().enumerate() {
12 let moves = possible_moves(
13 board,
14 idx as u8,
15 idx2 as u8,
16 match current {
17 types::PieceColor::Black => &types::PieceColor::White,
18 _ => &types::PieceColor::Black,
19 },
20 false,
21 );
22
23 for pmove in moves {
24 if pmove.x >= 0.
25 && pmove.x < 8.
26 && pmove.y >= 0.
27 && pmove.y < 8.
28 && matches!(
29 board[pmove.x as usize][pmove.y as usize],
30 types::Piece::King(_)
31 )
32 {
33 return true;
34 }
35 }
36 }
37 }
38 false
39}
40
41fn get_color(board: &Vec<Vec<types::Piece>>, x: u8, y: u8) -> Option<&types::PieceColor> {
42 if !((x as i8 >= 0 && x < 8) && (y as i8 >= 0 && y < 8)) {
43 return None;
44 }
45
46 match &board[x as usize][y as usize] {
47 types::Piece::Pawn(_color)
48 | types::Piece::Rook(_color)
49 | types::Piece::Knight(_color)
50 | types::Piece::Bishop(_color)
51 | types::Piece::Queen(_color)
52 | types::Piece::King(_color) => Some(_color),
53 types::Piece::Empty => None,
54 }
55}
56
57fn different_color(board: &Vec<Vec<types::Piece>>, x1: u8, y1: u8, x2: u8, y2: u8) -> bool {
58 if get_color(&board, x1, y1).is_none() && get_color(&board, x2, y2).is_none() {
59 return false;
60 }
61 if get_color(&board, x2, y2).is_none() {
62 return true;
63 }
64 if get_color(&board, x1, y1).is_none() {
65 return true;
66 }
67
68 match get_color(&board, x1, y1).unwrap() {
69 types::PieceColor::Black => match get_color(&board, x2, y2).unwrap() {
70 types::PieceColor::Black => false,
71 types::PieceColor::White => true,
72 },
73 types::PieceColor::White => match get_color(&board, x2, y2).unwrap() {
74 types::PieceColor::Black => true,
75 types::PieceColor::White => false,
76 },
77 }
78}
79
80fn possible_moves(
81 board: &Vec<Vec<types::Piece>>,
82 x: u8,
83 y: u8,
84 current: &types::PieceColor,
85 remove: bool,
86) -> Vec<Vec2> {
87 match &board[x as usize][y as usize] {
88 types::Piece::Pawn(_color)
89 | types::Piece::Rook(_color)
90 | types::Piece::Knight(_color)
91 | types::Piece::Bishop(_color)
92 | types::Piece::Queen(_color)
93 | types::Piece::King(_color) => {
94 if matches!(*current, types::PieceColor::Black)
95 && matches!(*_color, types::PieceColor::White)
96 {
97 return vec![];
98 }
99 if matches!(*current, types::PieceColor::White)
100 && matches!(*_color, types::PieceColor::Black)
101 {
102 return vec![];
103 }
104 }
105 types::Piece::Empty => {}
106 }
107
108 let mut possible: Vec<Vec2> = vec![];
109
110 match board[x as usize][y as usize] {
111 types::Piece::Pawn(color) => {
112 let y_offset: i8 = if matches!(color, types::PieceColor::Black) {
113 1
114 } else {
115 -1
116 };
117
118 let is_at_start: bool = (matches!(color, types::PieceColor::White) && y == 6)
119 || (matches!(color, types::PieceColor::Black) && y == 1);
120
121 if y as i8 + y_offset * 2 >= 0
122 && y as i8 + y_offset * 2 < 8
123 && matches!(
124 board[x as usize][(y as i8 + y_offset * 2) as usize],
125 types::Piece::Empty
126 )
127 && matches!(
128 board[x as usize][(y as i8 + y_offset) as usize],
129 types::Piece::Empty
130 )
131 && is_at_start
132 {
133 possible.push(Vec2::new(x as f32, y as f32 + y_offset as f32 * 2.));
134 }
135
136 if y as i8 + y_offset >= 0
137 && matches!(
138 board[x as usize][(y as i8 + y_offset) as usize],
139 types::Piece::Empty
140 )
141 {
142 possible.push(Vec2::new(x as f32, y as f32 + y_offset as f32));
143 }
144
145 for x_offset in [-1, 1] {
146 if !(x as i8 + x_offset >= 0
147 && x as i8 + x_offset < 8
148 && y as i8 + y_offset >= 0
149 && y as i8 + y_offset < 8)
150 {
151 continue;
152 }
153
154 if !matches!(
155 board[(x as i8 + x_offset) as usize][(y as i8 + y_offset) as usize],
156 types::Piece::Empty
157 ) {
158 let diff = different_color(
159 board,
160 x,
161 y,
162 (x as i8 + x_offset) as u8,
163 (y as i8 + y_offset) as u8,
164 );
165 if diff {
166 possible.push(Vec2::new(
167 (x as i8 + x_offset) as f32,
168 (y as i8 + y_offset) as f32,
169 ));
170 }
171 }
172 }
173 }
174 types::Piece::Knight(_) => {
175 if (x as i8 - 2 >= 0) && (y as i8 - 1 >= 0) {
176 if different_color(board, x, y, x - 2, y - 1) {
177 possible.push(Vec2::new(x as f32 - 2., y as f32 - 1.));
178 }
179 }
180 if (x as i8 - 1 >= 0) && (y as i8 - 2 >= 0) {
181 if different_color(board, x, y, x - 1, y - 2) {
182 possible.push(Vec2::new(x as f32 - 1., y as f32 - 2.));
183 }
184 }
185
186 if (x + 1 < 8) && (y as i8 - 2 >= 0) {
187 if different_color(board, x, y, x + 1, y - 2) {
188 possible.push(Vec2::new(x as f32 + 1., y as f32 - 2.));
189 }
190 }
191 if (x + 2 < 8) && (y as i8 - 1 >= 0) {
192 if different_color(board, x, y, x + 2, y - 1) {
193 possible.push(Vec2::new(x as f32 + 2., y as f32 - 1.));
194 }
195 }
196
197 if (x + 2 < 8) && (y + 1 < 8) {
198 if different_color(board, x, y, x + 2, y + 1) {
199 possible.push(Vec2::new(x as f32 + 2., y as f32 + 1.));
200 }
201 }
202 if (x + 1 < 8) && (y + 2 < 8) {
203 if different_color(board, x, y, x + 1, y + 2) {
204 possible.push(Vec2::new(x as f32 + 1., y as f32 + 2.));
205 }
206 }
207
208 if (x as i8 - 1 >= 0) && (y as i8 + 2 >= 0) {
209 if different_color(board, x, y, x - 1, y + 2) {
210 possible.push(Vec2::new(x as f32 - 1., y as f32 + 2.));
211 }
212 }
213 if (x as i8 - 2 >= 0) && (y + 1 < 8) {
214 if different_color(board, x, y, x - 2, y + 1) {
215 possible.push(Vec2::new(x as f32 - 2., y as f32 + 1.));
216 }
217 }
218 }
219 types::Piece::Rook(_) => {
220 for i in (0..x).rev() {
221 if get_color(board, i as u8, y).is_some() {
222 if different_color(board, x, y, i, y) {
223 possible.push(Vec2::new(i as f32, y as f32));
224 }
225 break;
226 }
227 possible.push(Vec2::new(i as f32, y as f32));
228 }
229
230 for i in (x + 1)..8 {
231 if get_color(board, i as u8, y).is_some() {
232 if different_color(board, x, y, i, y) {
233 possible.push(Vec2::new(i as f32, y as f32));
234 }
235 break;
236 }
237 possible.push(Vec2::new(i as f32, y as f32));
238 }
239
240 for i in (0..y).rev() {
241 if get_color(board, x, i as u8).is_some() {
242 if different_color(board, x, y, x, i) {
243 possible.push(Vec2::new(x as f32, i as f32));
244 }
245 break;
246 }
247 possible.push(Vec2::new(x as f32, i as f32));
248 }
249
250 for i in (y + 1)..8 {
251 if get_color(board, x, i as u8).is_some() {
252 if different_color(board, x, y, x, i) {
253 possible.push(Vec2::new(x as f32, i as f32));
254 }
255 break;
256 }
257 possible.push(Vec2::new(x as f32, i as f32));
258 }
259 }
260 types::Piece::Bishop(_) => {
261 for i in 1..8 {
262 if !(x + i < 8 && y + i < 8) {
263 continue;
264 }
265 if get_color(board, x + i, y + i).is_some() {
266 if different_color(board, x, y, x + i, y + i) {
267 possible.push(Vec2::new((x + i) as f32, (y + i) as f32));
268 }
269 break;
270 }
271 possible.push(Vec2::new((x + i) as f32, (y + i) as f32));
272 }
273
274 for i in 1..8 {
275 if !(x as i8 - i >= 0 && y as i8 - i >= 0) {
276 continue;
277 }
278 if get_color(board, x - i as u8, y - i as u8).is_some() {
279 if different_color(board, x, y, x - i as u8, y - i as u8) {
280 possible.push(Vec2::new((x - i as u8) as f32, (y - i as u8) as f32));
281 }
282 break;
283 }
284 possible.push(Vec2::new((x - i as u8) as f32, (y - i as u8) as f32));
285 }
286
287 for i in 1..8 {
288 if !(x as i8 + i < 8 && y as i8 - i >= 0) {
289 continue;
290 }
291 if get_color(board, x + i as u8, y - i as u8).is_some() {
292 if different_color(board, x, y, x + i as u8, y - i as u8) {
293 possible.push(Vec2::new((x + i as u8) as f32, (y - i as u8) as f32));
294 }
295 break;
296 }
297 possible.push(Vec2::new((x + i as u8) as f32, (y - i as u8) as f32));
298 }
299
300 for i in 1..8 {
301 if !(x as i8 - i >= 0 && y as i8 + i < 8) {
302 continue;
303 }
304 if get_color(board, x - i as u8, y + i as u8).is_some() {
305 if different_color(board, x, y, x - i as u8, y + i as u8) {
306 possible.push(Vec2::new((x - i as u8) as f32, (y + i as u8) as f32));
307 }
308 break;
309 }
310 possible.push(Vec2::new((x - i as u8) as f32, (y + i as u8) as f32));
311 }
312 }
313 types::Piece::King(_) => {
314 let i = 1;
315 if x + 1 < 8 && y + 1 < 8 {
316 if different_color(board, x, y, x + 1, y + 1) {
317 possible.push(Vec2::new((x + i) as f32, (y + i) as f32));
318 }
319 }
320 if y + 1 < 8 {
321 if different_color(board, x, y, x, y + i) {
322 possible.push(Vec2::new((x) as f32, (y + i) as f32));
323 }
324 }
325 if x as i8 - 1 >= 0 && y + 1 < 8 {
326 if different_color(board, x, y, x - 1, y + 1) {
327 possible.push(Vec2::new((x - i) as f32, (y + i) as f32));
328 }
329 }
330
331 if x + 1 < 8 {
332 if different_color(board, x, y, x + 1, y) {
333 possible.push(Vec2::new((x + i) as f32, (y) as f32));
334 }
335 }
336 if x as i8 - 1 >= 0 {
337 if different_color(board, x, y, x - 1, y) {
338 possible.push(Vec2::new((x - i) as f32, (y) as f32));
339 }
340 }
341
342 if x + 1 < 8 && y as i8 - 1 >= 0 {
343 if different_color(board, x, y, x + 1, y - 1) {
344 possible.push(Vec2::new((x + i) as f32, (y - i) as f32));
345 }
346 }
347 if y as i8 - 1 >= 0 {
348 if different_color(board, x, y, x, y - 1) {
349 possible.push(Vec2::new((x) as f32, (y - i) as f32));
350 }
351 }
352 if x as i8 > 0 && y as i8 > 0 {
353 if different_color(board, x, y, x - 1, y - 1) {
354 possible.push(Vec2::new((x - i) as f32, (y - i) as f32));
355 }
356 }
357 }
358 types::Piece::Queen(_) => {
359 for i in 1..8 {
360 if !(x as i8 + i < 8 && y as i8 + i < 8) {
361 continue;
362 }
363 if get_color(board, x + i as u8, y + i as u8).is_some() {
364 if different_color(board, x, y, x + i as u8, y + i as u8) {
365 possible.push(Vec2::new((x + i as u8) as f32, (y + i as u8) as f32));
366 }
367 break;
368 }
369 possible.push(Vec2::new((x + i as u8) as f32, (y + i as u8) as f32));
370 }
371
372 for i in 1..8 {
373 if !(x as i8 - i >= 0 && y as i8 - i >= 0) {
374 continue;
375 }
376 if get_color(board, x - i as u8, y - i as u8).is_some() {
377 if different_color(board, x, y, x - i as u8, y - i as u8) {
378 possible.push(Vec2::new((x - i as u8) as f32, (y - i as u8) as f32));
379 }
380 break;
381 }
382 possible.push(Vec2::new((x - i as u8) as f32, (y - i as u8) as f32));
383 }
384
385 for i in 1..8 {
386 if !(x as i8 + i < 8 && y as i8 - i >= 0) {
387 continue;
388 }
389 if get_color(board, x + i as u8, y - i as u8).is_some() {
390 if different_color(board, x, y, x + i as u8, y - i as u8) {
391 possible.push(Vec2::new((x + i as u8) as f32, (y - i as u8) as f32));
392 }
393 break;
394 }
395 possible.push(Vec2::new((x + i as u8) as f32, (y - i as u8) as f32));
396 }
397
398 for i in 1..8 {
399 if !(x as i8 - i >= 0 && y as i8 + i < 8) {
400 continue;
401 }
402 if get_color(board, x - i as u8, y + i as u8).is_some() {
403 if different_color(board, x, y, x - i as u8, y + i as u8) {
404 possible.push(Vec2::new((x - i as u8) as f32, (y + i as u8) as f32));
405 }
406 break;
407 }
408 possible.push(Vec2::new((x - i as u8) as f32, (y + i as u8) as f32));
409 }
410
411 for i in (0..x).rev() {
412 if get_color(board, i as u8, y).is_some() {
413 if different_color(board, x, y, i, y) {
414 possible.push(Vec2::new(i as f32, y as f32));
415 }
416 break;
417 }
418 possible.push(Vec2::new(i as f32, y as f32));
419 }
420
421 for i in (x + 1)..8 {
422 if get_color(board, i as u8, y).is_some() {
423 if different_color(board, x, y, i, y) {
424 possible.push(Vec2::new(i as f32, y as f32));
425 }
426 break;
427 }
428 possible.push(Vec2::new(i as f32, y as f32));
429 }
430
431 for i in (0..y).rev() {
432 if get_color(board, x, i as u8).is_some() {
433 if different_color(board, x, y, x, i) {
434 possible.push(Vec2::new(x as f32, i as f32));
435 }
436 break;
437 }
438 possible.push(Vec2::new(x as f32, i as f32));
439 }
440
441 for i in (y + 1)..8 {
442 if get_color(board, x, i as u8).is_some() {
443 if different_color(board, x, y, x, i) {
444 possible.push(Vec2::new(x as f32, i as f32));
445 }
446 break;
447 }
448 possible.push(Vec2::new(x as f32, i as f32));
449 }
450 }
451 _ => {}
452 }
453 if remove {
454 let length = possible.len();
455 for idx in (0..length).rev() {
456 let mut new_board: Vec<Vec<types::Piece>> = board.clone();
457
458 if x as i8 >= 0
459 && x < 8
460 && y as i8 >= 0
461 && y < 8
462 && possible[idx].x >= 0.
463 && possible[idx].x < 8.
464 && possible[idx].y >= 0.
465 && possible[idx].y < 8.
466 {
467 new_board[possible[idx].x as usize][possible[idx].y as usize] =
468 board[x as usize][y as usize];
469 new_board[x as usize][y as usize] = types::Piece::Empty;
470 }
471
472 if get_check(&new_board, current) {
473 possible.remove(idx);
474 }
475 }
476 }
477
478 possible
479}
480
481#[macroquad::main("Chess")]
482async fn main() {
483 //let background_color: Color = Color::from_rgba(251, 240, 240, 255);
484 //let white_color: Color = Color::from_rgba(251, 240, 240, 255);
485 //let black_color: Color = Color::from_rgba(124, 117, 117, 255);
486
487 let mut checkmate: Option<types::PieceColor> = None;
488
489 let white_color: Color = Color::from_rgba(98, 104, 128, 255);
490 let background_color: Color = Color::from_rgba(48, 52, 70, 255);
491 let black_color: Color = Color::from_rgba(48, 52, 70, 255);
492 let checked_color: Color = Color::from_rgba(255, 89, 123, 120);
493 let selected_color: Color = Color::from_rgba(163, 187, 152, 120);
494
495 let text_color: Color = Color::from_rgba(0, 0, 0, 60);
496
497 let arg = std::env::args().collect::<Vec<String>>();
498 let mut board: Vec<Vec<types::Piece>> = parse::parse_fen(if std::env::args().len() >= 2 {
499 arg[1].as_str()
500 } else {
501 "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"
502 });
503
504 let wking_tex = Texture2D::from_file_with_format(&get_wking_texture(), None);
505 let wqueen_tex = Texture2D::from_file_with_format(&get_wqueen_texture(), None);
506 let wbishop_tex = Texture2D::from_file_with_format(&get_wbishop_texture(), None);
507 let wknight_tex = Texture2D::from_file_with_format(&get_wknight_texture(), None);
508 let wrook_tex = Texture2D::from_file_with_format(&get_wrook_texture(), None);
509 let wpawn_tex = Texture2D::from_file_with_format(&get_wpawn_texture(), None);
510
511 let bking_tex = Texture2D::from_file_with_format(&get_bking_texture(), None);
512 let bqueen_tex = Texture2D::from_file_with_format(&get_bqueen_texture(), None);
513 let bbishop_tex = Texture2D::from_file_with_format(&get_bbishop_texture(), None);
514 let bknight_tex = Texture2D::from_file_with_format(&get_bknight_texture(), None);
515 let brook_tex = Texture2D::from_file_with_format(&get_brook_texture(), None);
516 let bpawn_tex = Texture2D::from_file_with_format(&get_bpawn_texture(), None);
517
518 // println!("{:?}", include_bytes!("../res/movedfrom.png"));
519
520 let movedfrom_tex = Texture2D::from_file_with_format(&get_movedfrom_texture(), None);
521
522 let mut selected: Option<Vec2> = None;
523 let mut last_selected: Option<Vec2> = None;
524
525 let mut current_color: types::PieceColor = types::PieceColor::White;
526
527 loop {
528 clear_background(background_color);
529
530 let min_val: f32 = if screen_width() > screen_height() {
531 screen_height()
532 } else {
533 screen_width()
534 };
535
536 let x_offset: f32 = if screen_width() > screen_height() {
537 (screen_width() - min_val) / 2.
538 } else {
539 0.
540 };
541 let y_offset: f32 = if screen_height() > screen_width() {
542 (screen_height() - min_val) / 2.
543 } else {
544 0.
545 };
546
547 if is_mouse_button_pressed(MouseButton::Left) && checkmate.is_none() {
548 let mut new_x = mouse_position().0;
549 let mut new_y = mouse_position().1;
550
551 new_x -= x_offset;
552 new_y -= y_offset;
553
554 new_x = (new_x / (min_val / 8.)).floor() * (min_val / 8.) / (min_val / 8.);
555 new_y = (new_y / (min_val / 8.)).floor() * (min_val / 8.) / (min_val / 8.);
556
557 println!("({}, {})", new_x, new_y);
558
559 if selected.is_none() {
560 if (0. ..8.).contains(&new_x) && (0. ..8.).contains(&new_y) {
561 selected = Some(Vec2::new(new_x, new_y));
562 last_selected = None;
563 }
564 } else {
565 if !possible_moves(
566 &board,
567 selected.unwrap().x as u8,
568 selected.unwrap().y as u8,
569 ¤t_color,
570 true,
571 )
572 .contains(&Vec2::new(new_x, new_y))
573 {
574 selected = None;
575 continue;
576 }
577
578 board[new_x as usize][new_y as usize] =
579 board[selected.unwrap().x as usize][selected.unwrap().y as usize];
580 board[selected.unwrap().x as usize][selected.unwrap().y as usize] =
581 types::Piece::Empty;
582
583 let mut black_possible = 0;
584 let mut white_possible = 0;
585
586 for x in 0..board.len() {
587 for y in 0..board[x].len() {
588 match &board[x][y] {
589 types::Piece::Pawn(_color)
590 | types::Piece::Rook(_color)
591 | types::Piece::Knight(_color)
592 | types::Piece::Bishop(_color)
593 | types::Piece::Queen(_color)
594 | types::Piece::King(_color) => {
595 if matches!(_color, types::PieceColor::Black) {
596 let col = types::PieceColor::Black;
597 black_possible +=
598 possible_moves(&board, x as u8, y as u8, &col, true).len();
599 } else {
600 let col = types::PieceColor::White;
601 white_possible +=
602 possible_moves(&board, x as u8, y as u8, &col, true).len();
603 }
604 }
605 types::Piece::Empty => {}
606 }
607 }
608 }
609
610 if black_possible == 0 {
611 checkmate = Some(types::PieceColor::White);
612 }
613 if white_possible == 0 {
614 checkmate = Some(types::PieceColor::Black);
615 }
616
617 if ((new_y == 7. && matches!(current_color, types::PieceColor::Black))
618 || (new_y == 0. && matches!(current_color, types::PieceColor::White)))
619 && matches!(board[new_x as usize][new_y as usize], types::Piece::Pawn(_))
620 {
621 board[new_x as usize][new_y as usize] = types::Piece::Queen(current_color);
622 }
623
624 current_color = match current_color {
625 types::PieceColor::White => types::PieceColor::Black,
626 types::PieceColor::Black => types::PieceColor::White,
627 };
628
629 last_selected = Some(Vec2::new(selected.unwrap().x, selected.unwrap().y));
630 selected = Some(Vec2::new(new_x, new_y));
631 }
632 }
633
634 for x in 0..8 {
635 for y in 0..8 {
636 let selected_unwrap = if selected.is_some() {
637 selected.unwrap()
638 } else {
639 Vec2::new(-1., -1.)
640 };
641 draw_rectangle(
642 x as f32 * (min_val / 8.) + x_offset,
643 y as f32 * (min_val / 8.) + y_offset,
644 min_val / 8.,
645 min_val / 8.,
646 if (x + y) % 2 == 0 {
647 white_color
648 } else {
649 black_color
650 },
651 );
652
653 if x == 0 {
654 //draw_text((8 - y).to_string().as_str(), x as f32 * (min_val / 8.) + x_offset, (y + 1) as f32 * (min_val / 8.) - (min_val / 8.) + y_offset + 42.0, 64.0, text_color);
655 }
656
657 if y == 7 {
658 let letter: &str = match x {
659 0 => "a",
660 1 => "b",
661 2 => "c",
662 3 => "d",
663 4 => "e",
664 5 => "f",
665 6 => "g",
666 7 => "h",
667 _ => "a",
668 };
669 //draw_text(letter, x as f32 * (min_val / 8.) + x_offset + (min_val / 8.) - 28., (y + 1) as f32 * (min_val / 8.) - (min_val / 8.) + y_offset + (min_val / 8.), 64.0, text_color);
670 }
671
672 let side_px: f32 = min_val / 8.;
673 let dest_size: Vec2 = Vec2::new(side_px, side_px);
674 let draw_params: DrawTextureParams = DrawTextureParams {
675 dest_size: Some(dest_size),
676 ..Default::default()
677 };
678
679 let x_pos = x as f32 * (min_val / 8.) + x_offset;
680 let y_pos = y as f32 * (min_val / 8.) + y_offset;
681
682 if last_selected.is_some()
683 && last_selected.unwrap() == Vec2::new(x as f32, y as f32)
684 {
685 draw_texture_ex(movedfrom_tex, x_pos, y_pos, WHITE, draw_params.clone());
686 }
687
688 if selected.is_some() && selected.unwrap() == Vec2::new(x as f32, y as f32) {
689 draw_rectangle(
690 x as f32 * (min_val / 8.) + x_offset,
691 y as f32 * (min_val / 8.) + y_offset,
692 min_val / 8.,
693 min_val / 8.,
694 selected_color,
695 );
696 }
697
698 match &board[x][y] {
699 types::Piece::Pawn(color) => {
700 draw_texture_ex(
701 match color {
702 types::PieceColor::Black => bpawn_tex,
703 _ => wpawn_tex,
704 },
705 x_pos,
706 y_pos,
707 WHITE,
708 draw_params,
709 );
710 }
711 types::Piece::Rook(color) => {
712 draw_texture_ex(
713 match color {
714 types::PieceColor::Black => brook_tex,
715 _ => wrook_tex,
716 },
717 x_pos,
718 y_pos,
719 WHITE,
720 draw_params,
721 );
722 }
723 types::Piece::Knight(color) => {
724 draw_texture_ex(
725 match color {
726 types::PieceColor::Black => bknight_tex,
727 _ => wknight_tex,
728 },
729 x_pos,
730 y_pos,
731 WHITE,
732 draw_params,
733 );
734 }
735 types::Piece::Bishop(color) => {
736 draw_texture_ex(
737 match color {
738 types::PieceColor::Black => bbishop_tex,
739 _ => wbishop_tex,
740 },
741 x_pos,
742 y_pos,
743 WHITE,
744 draw_params,
745 );
746 }
747 types::Piece::Queen(color) => {
748 draw_texture_ex(
749 match color {
750 types::PieceColor::Black => bqueen_tex,
751 _ => wqueen_tex,
752 },
753 x_pos,
754 y_pos,
755 WHITE,
756 draw_params,
757 );
758 }
759 types::Piece::King(color) => {
760 let current_equals = match color {
761 types::PieceColor::Black => match current_color {
762 types::PieceColor::Black => true,
763 types::PieceColor::White => false,
764 },
765 types::PieceColor::White => match current_color {
766 types::PieceColor::Black => false,
767 types::PieceColor::White => true,
768 },
769 };
770
771 if current_equals && get_check(&board, ¤t_color) {
772 draw_rectangle(x_pos, y_pos, min_val / 8., min_val / 8., checked_color);
773 }
774
775 draw_texture_ex(
776 match color {
777 types::PieceColor::Black => bking_tex,
778 _ => wking_tex,
779 },
780 x_pos,
781 y_pos,
782 WHITE,
783 draw_params,
784 );
785 }
786 _ => {}
787 }
788 }
789 }
790
791 if selected.is_some() {
792 let available_moves = possible_moves(
793 &board,
794 selected.unwrap().x as u8,
795 selected.unwrap().y as u8,
796 ¤t_color,
797 true,
798 );
799
800 for x in available_moves {
801 draw_rectangle(
802 x.x as f32 * (min_val / 8.) + x_offset,
803 x.y as f32 * (min_val / 8.) + y_offset,
804 min_val / 8.,
805 min_val / 8.,
806 selected_color,
807 );
808 }
809 }
810
811 let render_target = render_target(400, 400);
812 render_target.texture.set_filter(FilterMode::Linear);
813
814 set_camera(&Camera2D {
815 zoom: vec2(0.005, 0.005),
816 target: vec2(0.0, 0.0),
817 render_target: Some(render_target),
818 ..Default::default()
819 });
820
821 if checkmate.is_none() {
822 match current_color {
823 types::PieceColor::Black => draw_text("Black's turn", -190., -170., 32., BLACK),
824 types::PieceColor::White => draw_text("White's turn", -190., -170., 32., WHITE),
825 };
826 }
827
828 if checkmate.is_some() {
829 draw_text(
830 match checkmate.unwrap() {
831 types::PieceColor::Black => "Black Wins!",
832 types::PieceColor::White => "White Wins!",
833 },
834 -190.,
835 -160.,
836 64.,
837 WHITE,
838 );
839 draw_text("Press to restart", -190., -130., 32., WHITE);
840 }
841
842 set_default_camera();
843
844 draw_texture_ex(
845 render_target.texture,
846 0.,
847 0.,
848 WHITE,
849 DrawTextureParams {
850 dest_size: Some(Vec2::new(400., 400.)),
851 ..Default::default()
852 },
853 );
854
855 draw_texture_ex(
856 render_target.texture,
857 screen_width(),
858 screen_height(),
859 WHITE,
860 DrawTextureParams {
861 dest_size: Some(Vec2::new(-400., -400.)),
862 ..Default::default()
863 },
864 );
865
866 next_frame().await
867 }
868}