a simple chess game to play locally on a tablet or with a mouse
at master 32 kB view raw
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 &current_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, &current_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 &current_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}