Advertisement
Guest User

minimax tictactoe implemented in V

a guest
Aug 29th, 2023
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.03 KB | None | 0 0
  1. // tic tac toe piece type
  2. enum Piece {
  3. x
  4. o
  5. blank
  6. }
  7.  
  8. // Board type used for minimax & to store the game board
  9. struct Board {
  10. mut:
  11. board []Piece
  12. }
  13.  
  14. // Creates a new Board with a given move, used for minimax
  15. fn (b Board) move(idx int, p Piece) Board {
  16. mut new_board := b.board.clone()
  17. new_board[idx] = p
  18. return Board { board: new_board }
  19. }
  20.  
  21. // Gets the piece at a given index
  22. fn (b Board) get(idx int) Piece {
  23. return b.board[idx]
  24. }
  25.  
  26. // Sets the piece at a given index
  27. fn (mut b Board) set(idx int, p Piece) {
  28. b.board[idx] = p
  29. }
  30.  
  31. // Creates a new board with no placed pieces
  32. fn new_board() Board {
  33. return Board{ board: []Piece{len: 9, init: Piece.blank} }
  34. }
  35.  
  36. // Prints out the Board
  37. fn (b Board) print_board() {
  38. mut i := 0
  39. for y in 0..3 {
  40. for x in 0..3 {
  41. p := b.get(i)
  42. if p == Piece.blank {
  43. print(i)
  44. }
  45. else {
  46. print(p)
  47. }
  48. if x < 2 {
  49. print('|')
  50. }
  51.  
  52. i += 1
  53. }
  54. if y < 2 {
  55. println('\n-----')
  56. }
  57. }
  58. println('')
  59. }
  60.  
  61. // Checks along a 3-square row/diagonal to see if a specific color has won
  62. fn (b Board) check(sx int, sy int, stepx int, stepy int, color Piece) bool {
  63. mut x := sx
  64. mut y := sy
  65. for _ in 0..3 {
  66. next := b.get(y * 3 + x)
  67. if next != color {
  68. return false
  69. }
  70.  
  71. x += stepx
  72. y += stepy
  73. }
  74. return true
  75. }
  76.  
  77. // Checks all rows/diagonals to see if a specific color has won
  78. fn (b Board) is_winner(color Piece) bool {
  79. if b.check(0, 0, 1, 0, color) { return true }
  80. if b.check(0, 1, 1, 0, color) { return true }
  81. if b.check(0, 2, 1, 0, color) { return true }
  82.  
  83. if b.check( 0, 0, 0, 1, color) { return true }
  84. if b.check(1, 0, 0, 1, color) { return true }
  85. if b.check(2, 0, 0, 1, color) { return true }
  86.  
  87. if b.check(0, 0, 1, 1, color) { return true }
  88. if b.check(2, 0, -1, 1, color) { return true }
  89.  
  90. return false
  91. }
  92.  
  93. // Checks both colors to see if either has won, then returns that color
  94. fn (b Board) winner() Piece {
  95. if b.is_winner(Piece.x) { return Piece.x }
  96. if b.is_winner(Piece.o) { return Piece.o }
  97.  
  98. return Piece.blank
  99. }
  100.  
  101. // Gets all the legal moves for a piece
  102. fn (b Board) moves() []int {
  103. mut m := []int{len: 0}
  104. for i in 0..9 {
  105. if b.get(i) == Piece.blank {
  106. m << i
  107. }
  108. }
  109. return m
  110. }
  111.  
  112. // Performs the minimax algorithm. Basically copied from wikipedia
  113. fn minimax(board Board, maximize bool) int {
  114. win := board.winner()
  115. if win == Piece.x { return 10 }
  116. if win == Piece.o { return -10 }
  117.  
  118. move_list := board.moves()
  119. if move_list.len == 0 {
  120. return 0 // draw
  121. }
  122.  
  123. if maximize {
  124. mut value := -10
  125. for m in move_list {
  126. next := board.move(m, Piece.x)
  127. next_value := minimax(next, false)
  128. if next_value > value { value = next_value }
  129. }
  130. return value
  131. }
  132. else {
  133. mut value := 10
  134. for m in move_list {
  135. next := board.move(m, Piece.o)
  136. next_value := minimax(next, true)
  137. if next_value < value { value = next_value }
  138. }
  139. return value
  140. }
  141. }
  142.  
  143. // A simpler AI used for X's moves.
  144. fn fake_move(board Board) int {
  145. for i in 0..9 {
  146. if board.get(i) == Piece.blank {
  147. return i
  148. }
  149. }
  150. return 0
  151. }
  152.  
  153. fn main() {
  154. // Create the game board
  155. mut board := new_board()
  156.  
  157. for i in 0..5 {
  158. // Print initial board
  159. board.print_board()
  160.  
  161. // Get X's move
  162. a := fake_move(board)
  163.  
  164. // Perform X's move
  165. board.set(a, Piece.x)
  166.  
  167. // Print board after each move
  168. board.print_board()
  169.  
  170. // O does not get a last move
  171. if i == 4 {
  172. return
  173. }
  174.  
  175. println('bot is thinking --- ')
  176.  
  177. mut best_ai := 0
  178. // even larger than actual worst score to force an assignment
  179. mut best_score := 100000
  180.  
  181. // Look through all moves to see which one is best
  182. for ai in 0..9 {
  183. // Skip illegal moves
  184. if board.get(ai) != Piece.blank {
  185. continue
  186. }
  187.  
  188. // Perform minimax to score the move
  189. test := board.move(ai, Piece.o)
  190. // Test x's responses to our move
  191. score := minimax(test, true)
  192.  
  193. if score < best_score {
  194. best_ai = ai
  195. best_score = score
  196. }
  197. }
  198.  
  199. // Perform O's move
  200. board.set(best_ai, Piece.o)
  201. }
  202. }
Tags: minimax vl
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement