你的任务是模拟黑白棋游戏的进程。黑白棋的规则为:黑白双方轮流放棋子,每次必须让新放的棋子“夹住”至少一枚对方棋子,然后把所有被新放棋子“夹住”的对方棋子替换成己方棋子。一段连续(横、竖或者斜向)的同色棋子被“夹住”的条件是两端都是对方棋子(不能是空位)。如图4-6(a)所示,白棋有6个合法操作,分别为(2,3),(3,3),(3,5),(6,2),(7,3),(7,4)。选择在(7,3)放白棋后变成如图4-6(b)所示效果(注意有竖向和斜向的共两枚黑棋变白)。注意(4,6)的黑色棋子虽然被夹住,但不是被新放的棋子夹住,因此不变白。
输入一个8*8的棋盘以及当前下一次操作的游戏者,处理3种指令:
样例:
输入
--------
--------
--------
---WB---
---BW---
--------
--------
--------
W
L
M35
L
Q
输出
[(3, 5), (4, 6), (5, 3), (6, 4)]
W is 4. B is 1
[(3, 4), (3, 6), (5, 6)]
--------
--------
----W---
---WW---
---BW---
--------
--------
--------
解法:
use std::io;
enum Cmd {
Print,
Move(usize, usize),
Quit,
}
fn main() {
let mut grid: Vec<Vec<char>> = vec![];
for _i in 0..8 {
let mut buf = String::new();
io::stdin().read_line(&mut buf).unwrap();
grid.push(buf.trim().chars().collect());
}
let mut buf = String::new();
io::stdin().read_line(&mut buf).unwrap();
let mut curplayer = buf.trim().chars().nth(0).unwrap();
let mut cmds: Vec<Cmd> = vec![];
loop {
let mut buf = String::new();
io::stdin().read_line(&mut buf).unwrap();
buf = buf.trim().to_string();
if buf == "L" {
cmds.push(Cmd::Print);
} else if buf == "Q" {
cmds.push(Cmd::Quit);
break;
} else {
let i = buf.chars().nth(1).unwrap().to_digit(10).unwrap();
let j = buf.chars().nth(2).unwrap().to_digit(10).unwrap();
cmds.push(Cmd::Move(i as usize, j as usize));
}
}
for i in cmds {
match i {
Cmd::Print => printmoves(&grid, curplayer),
Cmd::Move(x, y) => fangzi(&mut grid, &mut curplayer, (x, y)),
Cmd::Quit => {
printgrid(&grid);
break;
}
}
}
}
fn fangzi(grid: &mut Vec<Vec<char>>, curp: &mut char, pos: (usize, usize)) {
let allmoves = getmoves(grid, *curp);
if allmoves.is_empty() {
*curp = oposite(*curp);
}
let newpos = (pos.0 - 1, pos.1 - 1);
grid[newpos.0][newpos.1] = *curp;
let runs = [
(0, -1),
(0, 1),
(-1, 0),
(1, 0),
(-1, -1),
(1, 1),
(-1, 1),
(1, -1),
];
for d in runs {
if judge(grid, *curp, newpos, d) {
change(grid, *curp, newpos, d);
}
}
let nums = getnums(grid);
println!("W is {}. B is {}", nums.0, nums.1);
*curp = oposite(*curp);
}
fn getnums(grid: &Vec<Vec<char>>) -> (u32, u32) {
let mut nums = (0, 0);
for i in 0..8 {
for j in 0..8 {
if grid[i][j] == 'W' {
nums.0 += 1;
} else if grid[i][j] == 'B' {
nums.1 += 1;
}
}
}
return nums;
}
fn oposite(p: char) -> char {
if p == 'W' {
'B'
} else {
'W'
}
}
fn printgrid(grid: &Vec<Vec<char>>) {
for line in grid.iter() {
println!("{}", line.iter().collect::<String>());
}
}
fn getmoves(grid: &Vec<Vec<char>>, curp: char) -> Vec<(usize, usize)> {
let mut allmoves: Vec<(usize, usize)> = vec![];
let runs = [
(0, -1),
(0, 1),
(-1, 0),
(1, 0),
(-1, -1),
(1, 1),
(-1, 1),
(1, -1),
];
for i in 0..8 {
for j in 0..8 {
//println!("i,j: {},{}", i, j);
if grid[i][j] != '-' {
continue;
}
for d in runs {//检查八个方向
if judge(grid, curp, (i, j), d) {
allmoves.push((i + 1, j + 1));
break;
}
}
}
}
return allmoves;
}
fn judge(grid: &Vec<Vec<char>>, curp: char, pos: (usize, usize), run: (i32, i32)) -> bool {
let mut x = pos.0;
let mut y = pos.1;
let mut bjiazhu = false;
while x > 0 && x < 7 && y > 0 && y < 7 {
x = (x as i32 + run.0) as usize;
y = (y as i32 + run.1) as usize;
if grid[x][y] == '-'{
break;
}
if grid[x][y] == oposite(curp) {
bjiazhu = true;
}else if bjiazhu {
return true;
}else {
break;
}
}
return false;
}
fn change(grid: &mut Vec<Vec<char>>, curp: char, pos: (usize, usize), run: (i32, i32)) {
let mut x = pos.0;
let mut y = pos.1;
while x > 0 && x < 7 && y > 0 && y < 7 {
x = (x as i32 + run.0) as usize;
y = (y as i32 + run.1) as usize;
if grid[x][y] == oposite(curp) {
grid[x][y] = curp;
} else {
return;
}
}
}
fn printmoves(grid: &Vec<Vec<char>>, curp: char) {
let allmoves = getmoves(grid, curp);
if allmoves.is_empty() {
println!("No legal move");
} else {
println!("{:?}", allmoves);
}
}