Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // tic tac toe piece type
- enum Piece {
- x
- o
- blank
- }
- // Board type used for minimax & to store the game board
- struct Board {
- mut:
- board []Piece
- }
- // Creates a new Board with a given move, used for minimax
- fn (b Board) move(idx int, p Piece) Board {
- mut new_board := b.board.clone()
- new_board[idx] = p
- return Board { board: new_board }
- }
- // Gets the piece at a given index
- fn (b Board) get(idx int) Piece {
- return b.board[idx]
- }
- // Sets the piece at a given index
- fn (mut b Board) set(idx int, p Piece) {
- b.board[idx] = p
- }
- // Creates a new board with no placed pieces
- fn new_board() Board {
- return Board{ board: []Piece{len: 9, init: Piece.blank} }
- }
- // Prints out the Board
- fn (b Board) print_board() {
- mut i := 0
- for y in 0..3 {
- for x in 0..3 {
- p := b.get(i)
- if p == Piece.blank {
- print(i)
- }
- else {
- print(p)
- }
- if x < 2 {
- print('|')
- }
- i += 1
- }
- if y < 2 {
- println('\n-----')
- }
- }
- println('')
- }
- // Checks along a 3-square row/diagonal to see if a specific color has won
- fn (b Board) check(sx int, sy int, stepx int, stepy int, color Piece) bool {
- mut x := sx
- mut y := sy
- for _ in 0..3 {
- next := b.get(y * 3 + x)
- if next != color {
- return false
- }
- x += stepx
- y += stepy
- }
- return true
- }
- // Checks all rows/diagonals to see if a specific color has won
- fn (b Board) is_winner(color Piece) bool {
- if b.check(0, 0, 1, 0, color) { return true }
- if b.check(0, 1, 1, 0, color) { return true }
- if b.check(0, 2, 1, 0, color) { return true }
- if b.check( 0, 0, 0, 1, color) { return true }
- if b.check(1, 0, 0, 1, color) { return true }
- if b.check(2, 0, 0, 1, color) { return true }
- if b.check(0, 0, 1, 1, color) { return true }
- if b.check(2, 0, -1, 1, color) { return true }
- return false
- }
- // Checks both colors to see if either has won, then returns that color
- fn (b Board) winner() Piece {
- if b.is_winner(Piece.x) { return Piece.x }
- if b.is_winner(Piece.o) { return Piece.o }
- return Piece.blank
- }
- // Gets all the legal moves for a piece
- fn (b Board) moves() []int {
- mut m := []int{len: 0}
- for i in 0..9 {
- if b.get(i) == Piece.blank {
- m << i
- }
- }
- return m
- }
- // Performs the minimax algorithm. Basically copied from wikipedia
- fn minimax(board Board, maximize bool) int {
- win := board.winner()
- if win == Piece.x { return 10 }
- if win == Piece.o { return -10 }
- move_list := board.moves()
- if move_list.len == 0 {
- return 0 // draw
- }
- if maximize {
- mut value := -10
- for m in move_list {
- next := board.move(m, Piece.x)
- next_value := minimax(next, false)
- if next_value > value { value = next_value }
- }
- return value
- }
- else {
- mut value := 10
- for m in move_list {
- next := board.move(m, Piece.o)
- next_value := minimax(next, true)
- if next_value < value { value = next_value }
- }
- return value
- }
- }
- // A simpler AI used for X's moves.
- fn fake_move(board Board) int {
- for i in 0..9 {
- if board.get(i) == Piece.blank {
- return i
- }
- }
- return 0
- }
- fn main() {
- // Create the game board
- mut board := new_board()
- for i in 0..5 {
- // Print initial board
- board.print_board()
- // Get X's move
- a := fake_move(board)
- // Perform X's move
- board.set(a, Piece.x)
- // Print board after each move
- board.print_board()
- // O does not get a last move
- if i == 4 {
- return
- }
- println('bot is thinking --- ')
- mut best_ai := 0
- // even larger than actual worst score to force an assignment
- mut best_score := 100000
- // Look through all moves to see which one is best
- for ai in 0..9 {
- // Skip illegal moves
- if board.get(ai) != Piece.blank {
- continue
- }
- // Perform minimax to score the move
- test := board.move(ai, Piece.o)
- // Test x's responses to our move
- score := minimax(test, true)
- if score < best_score {
- best_ai = ai
- best_score = score
- }
- }
- // Perform O's move
- board.set(best_ai, Piece.o)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement