use std::io::{self, Write};
#[derive(Clone, Copy)]
struct Board {
squares: [[Option<Piece>; 8]; 8],
}
#[derive(Clone, Copy)]
struct Piece {
kind: PieceKind,
color: Color,
}
#[derive(Clone, Copy, PartialEq)]
enum PieceKind {
Pawn,
Rook,
Knight,
Bishop,
Queen,
King,
}
#[derive(Clone, Copy, PartialEq)]
enum Color {
White,
Black,
}
impl Board {
fn new() -> Self {
let mut board = Board {
squares: [[None; 8]; 8],
};
for i in 0..8 {
board.squares[1][i] = Some(Piece {
kind: PieceKind::Pawn,
color: Color::Black,
});
board.squares[6][i] = Some(Piece {
kind: PieceKind::Pawn,
color: Color::White,
});
}
let black_back = [
PieceKind::Rook,
PieceKind::Knight,
PieceKind::Bishop,
PieceKind::Queen,
PieceKind::King,
PieceKind::Bishop,
PieceKind::Knight,
PieceKind::Rook,
];
for i in 0..8 {
board.squares[0][i] = Some(Piece {
kind: black_back[i],
color: Color::Black,
});
}
let white_back = [
PieceKind::Rook,
PieceKind::Knight,
PieceKind::Bishop,
PieceKind::Queen,
PieceKind::King,
PieceKind::Bishop,
PieceKind::Knight,
PieceKind::Rook,
];
for i in 0..8 {
board.squares[7][i] = Some(Piece {
kind: white_back[i],
color: Color::White,
});
}
board
}
fn print(&self) {
println!("\n a b c d e f g h");
for rank in (0..8).rev() {
print!("{} ", rank + 1);
for file in 0..8 {
match self.squares[rank][file] {
Some(piece) => {
let symbol = match piece.kind {
PieceKind::Pawn => {
if piece.color == Color::White {
'♙'
} else {
'♟'
}
}
PieceKind::Rook => {
if piece.color == Color::White {
'♖'
} else {
'♜'
}
}
PieceKind::Knight => {
if piece.color == Color::White {
'♘'
} else {
'♞'
}
}
PieceKind::Bishop => {
if piece.color == Color::White {
'♗'
} else {
'♝'
}
}
PieceKind::Queen => {
if piece.color == Color::White {
'♕'
} else {
'♛'
}
}
PieceKind::King => {
if piece.color == Color::White {
'♔'
} else {
'♚'
}
}
};
print!("{} ", symbol);
}
None => print!(". "),
}
}
println!("{}", rank + 1);
}
println!(" a b c d e f g h\n");
}
fn move_piece(&mut self, from: (usize, usize), to: (usize, usize)) -> bool {
let piece = match self.squares[from.0][from.1] {
Some(p) => p,
None => return false,
};
if let Some(target) = self.squares[to.0][to.1] {
if target.color == piece.color {
return false;
}
}
let row_diff = (to.0 as i32 - from.0 as i32).abs();
let col_diff = (to.1 as i32 - from.1 as i32).abs();
let valid = match piece.kind {
PieceKind::Pawn => {
let dir = if piece.color == Color::White { -1 } else { 1 };
let new_row = from.0 as i32 + dir;
if new_row == to.0 as i32 && col_diff == 0 && self.squares[to.0][to.1].is_none() {
true
} else if new_row == to.0 as i32 && col_diff == 1 && self.squares[to.0][to.1].is_some() {
true
} else {
false
}
}
PieceKind::Rook => from.0 == to.0 || from.1 == to.1,
PieceKind::Knight => (row_diff == 2 && col_diff == 1) || (row_diff == 1 && col_diff == 2),
PieceKind::Bishop => row_diff == col_diff,
PieceKind::Queen => from.0 == to.0 || from.1 == to.1 || row_diff == col_diff,
PieceKind::King => row_diff <= 1 && col_diff <= 1,
};
if valid {
self.squares[to.0][to.1] = self.squares[from.0][from.1];
self.squares[from.0][from.1] = None;
true
} else {
false
}
}
fn get_square_coords(input: &str) -> Option<(usize, usize)> {
let chars: Vec<char> = input.trim().to_lowercase().chars().collect();
if chars.len() != 2 {
return None;
}
let file = match chars[0] {
'a' => 0,
'b' => 1,
'c' => 2,
'd' => 3,
'e' => 4,
'f' => 5,
'g' => 6,
'h' => 7,
_ => return None,
};
let rank = match chars[1].to_digit(10) {
Some(r) if (1..=8).contains(&r) => (r - 1) as usize,
_ => return None,
};
Some((rank, file))
}
}
fn main() {
let mut board = Board::new();
let mut turn = Color::White;
println!("=== ШАХМАТЫ ДЛЯ ПЯТИЛЕТКИ ===");
println!("Вводи ходы как: e2 e4");
println!("Белые ходят первыми\n");
loop {
board.print();
let color_name = if turn == Color::White { "Белые" } else { "Черные" };
print!("{}: ", color_name);
io::stdout().flush().unwrap();
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
let parts: Vec<&str> = input.trim().split_whitespace().collect();
if parts.len() != 2 {
println!("Непонятно. Пиши как: e2 e4\n");
continue;
}
let from = Board::get_square_coords(parts[0]);
let to = Board::get_square_coords(parts[1]);
match (from, to) {
(Some(f), Some(t)) => {
if let Some(piece) = board.squares[f.0][f.1] {
if piece.color != turn {
println!("Сейчас ходят {}!\n", color_name);
continue;
}
}
if board.move_piece(f, t) {
turn = if turn == Color::White {
Color::Black
} else {
Color::White
};
} else {
println!("Так нельзя! Попробуй еще раз\n");
}
}
_ => {
println!("Неправильные координаты. Используй a1, b2 и т.д.\n");
}
}
}
}