2️⃣
Rustを勉強しようと思ったらgithub copilotに全部書かれた
最近Rustの勉強を始めました。
The Bookの7章ぐらいまで呼んだところで無性に何かを作りたくなったので、オセロを作ることにしました。
完全にオセロを再現することが目的ではなく、あくまで「それっぽく」ターミナル上で動くものを作れたらと思い、コードを書き始めました。
成果物
とりあえず必要なものをコメントでメモしようとすると、あれよあれよという間にコードが生成されていくのです...!自分でコード書きたいのに。笑
github copilotは便利だし、日頃の業務で助けてくれるけど勉強する時はあえてOFFにした方が良いかもしれないですね。
完成したコードがこちら。
自分が手を加えたのは、オセロの盤面での表示ぐらいです。笑
コード
fn main() {
let mut board = Board::new();
board.print();
// ループを使って交互に石を置く
let mut turn = Stone::Black;
loop {
println!("{:?}のターンです", turn);
let mut input = String::new();
std::io::stdin().read_line(&mut input).unwrap();
let input: Vec<usize> = input
.split_whitespace()
.map(|s| s.parse().unwrap())
.collect();
board.put(input[0], input[1], turn);
board.reverse(input[0], input[1], turn);
board.print();
turn = match turn {
Stone::Black => Stone::White,
Stone::White => Stone::Black,
Stone::None => Stone::None,
};
}
}
// オセロの盤面を表す構造体
const BOARD_SIZE: usize = 8;
// オセロの石を表す列挙型
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
enum Stone {
Black,
White,
None,
}
// オセロの盤面を表す構造体
struct Board {
board: [[Stone; BOARD_SIZE]; BOARD_SIZE],
}
impl Board {
// オセロの盤面を初期化する関数
fn new() -> Board {
let mut board = [[Stone::None; BOARD_SIZE]; BOARD_SIZE];
board[3][3] = Stone::White;
board[3][4] = Stone::Black;
board[4][3] = Stone::Black;
board[4][4] = Stone::White;
Board { board }
}
// オセロの盤面を表示する関数
fn print(&self) {
for i in 0..BOARD_SIZE {
for j in 0..BOARD_SIZE {
match self.board[i][j] {
Stone::Black => print!(" ⚪︎ "),
Stone::White => print!(" ⚫︎ "),
Stone::None => print!("({}{})", j, i),
}
}
println!();
}
}
}
// オセロの石を置く関数
impl Board {
fn put(&mut self, x: usize, y: usize, stone: Stone) {
if x < BOARD_SIZE && y < BOARD_SIZE {
self.board[y][x] = stone;
}
}
}
// オセロの石をひっくり返す関数
impl Board {
fn reverse(&mut self, x: usize, y: usize, stone: Stone) {
let mut reverse = Vec::new();
for dx in -1..=1 {
for dy in -1..=1 {
if dx == 0 && dy == 0 {
continue;
}
let mut x = x as i32;
let mut y = y as i32;
let mut tmp = Vec::new();
loop {
x += dx;
y += dy;
if x < 0 || x >= BOARD_SIZE as i32 || y < 0 || y >= BOARD_SIZE as i32 {
break;
}
match self.board[y as usize][x as usize] {
Stone::None => break,
s if s == stone => {
reverse.append(&mut tmp);
break;
}
_ => tmp.push((x as usize, y as usize)),
}
}
}
}
for (x, y) in reverse {
self.board[y][x] = stone;
}
}
}
Discussion