Initializing board

advertisement
Othello Game Programs
(human to human)
1
The rule of the game
Othello is played on a 8-by-8 board, which is initially set up with four pieces in the center. Two
players, black and white, alternate turns, with black playing first. Each piece must be placed so
that it brackets one or more opponent pieces.The intervening white pieces are flipped over to
black, and vice verse.
Initializing board (1)
(defconstant all-directs '(-11 -10 -9 -1 1 9 10 11))
ALL-DIRECTS
(defconstant empty 0)
EMPTY
(defconstant black 1)
BLACK
(defconstant white 2)
WHITE
(defconstant outer 3)
OUTER
(deftype piece () `(integer ,empty ,outer))
PIECE
(defun name-of (piece) (char ".@0?" piece))
NAME-OF
2
(defun opponent (player) (if (eql player black)
white
black))
OPPONENT
(defconstant all-squares
(deftype board () '(simple-array piece (100)))
'(1 2 3 4 5 6 7 8
11 12 13 14 15 16 17 18
BOARD
21 22 23 24 25 26 27 28
31 32 33 34 35 36 37 38
(defun copy-board (board)
(copy-seq board))
41 42 43 44 45 46 47 48
51 52 53 54 55 56 57 58
61 62 63 64 65 66 67 68
COPY-BOARD
71 72 73 74 75 76 77 78
(defconstant all-squares
81 82 83 84 85 86 87 88 ))
(loop for
i from 11 to 88
when (<= 1 (mod i 10) 8) collect i))
ALL-SQUARES
(defun count-difference (player board)
(- (count player board)
(count (opponent player) board)))
COUNT-DIFFERENCE
3
(defun initial-board ()
(let ((board (make-array 100 :element-type 'piece
:initial-element
outer )))
(dolist (square all-squares)
(setf (bref board square) empty))
(setf (aref board 44) white (aref board 45) black
(aref board 54) black (aref board 55) white)
board))
INITIAL-BOARD
(defun print-board (board)
(format t "~2&
1 2 3 4 5 6 7 8
[~c=~2a ~c=~2a (~@d)]"
(name-of black) (count black board)
(name-of white) (count white board)
(count-difference black board))
(loop for row from 1 to 8 do
(format t "~&
~d " (* 10 row))
(loop for col from 1 to 8
for piece = (aref board (+ col (* 10 row)))
do (format t "~c " (name-of piece))))
(format t "~2&"))
4
(write (initial-board)
:array t)
#(3 3 3 3 3 3 3 3 3 3 3 0 0 0 0 0 0 0 0 3 3 0 0 0 0 0 0 0 0 3 3 0 0 0
0 0 0 0 0 3 3 0 0 0 2 1 0 0 0 3 3 0 0 0 1 2 0 0 0 3 3 0 0 0 0 0 0 0 0
3 3 0 0 0 0 0 0 0 0 3 3 0 0 0 0 0 0 0 0 3 3 3 3 3 3 3 3 3 3 3)
#(3 3 3 3 3 3 3 3 3 3 ...)
(print-board (initial-board))
1 2 3 4 5 6 7 8
[@=2
0=2
(0)]
10 . . . . . . . .
20 . . . . . . . .
30 . . . . . . . .
40 . . . 0 @ . . .
50 . . . @ 0 . . .
60 . . . . . . . .
70 . . . . . . . .
80 . . . . . . . .
NIL
5
(defun valid-p (move)
(and (integerp move) (<= 11 move 88) (<= 1 (mod move 10) 8)))
VALID-P
(valid-p 60)
NIL
(valid-p 43)
(defun legal-p (move player board)
T
(and (eql (aref board move) empty)
(some #'(lambda (dir) (would-flip? move player board dir))
all-directions)))
LEGAL-P
(defun would-flip? (move player board dir)
(let ((c (+ move dir)))
(and (eql (aref board c) (opponent player))
(find-bracketing-piece (+ c dir) player board dir))))
WOULD-FLIP?
(defun find-bracketing-piece (square player board dir)
(cond ((eql (aref board square) player) square)
((eql (aref board square) (opponent player))
(find-bracketing-piece (+ square dir) player board dir))
(t nil)))
FIND-BRACKETING-PIECE
(legal-p 43 black (initial-board))
45
(legal-p 42 black (initial-board))
NIL
6
(defun make-move (move player board)
(setf (aref board move) player)
(dolist (dir all-directions)
(make-flips move player board dir))
board)
MAKE-MOVE
(defun make-flips (move player board dir)
(let ((bracketer (would-flip? move player board dir)))
(when bracketer
(loop for c from (+ move dir) by dir until (eql c bracketer)
do (setf (aref board c) player)))))
MAKE-FLIPS
(print-board (make-move 56 black (initial-board)))
1 2 3 4 5 6 7 8
[@=4
0=1
(+3)]
10 / / / / / / / /
20 / / / / / / / /
(make-move 56 black (initial-board))
30 / / / / / / / /
#(3
0 0
3 3
0 0
3)
40 / / / 0 @ / / /
50 / / / @ @ @ / /
60 / / / / / / / /
3
0
0
0
3
0
0
0
3
0
0
0
3
3
1
3
3
3
1
3
3
0
1
0
3
0
0
0
3
0
0
0
3
0
3
0
3
0
3
0
0
0
0
0
0
0
0
0
0
0
0
0
0
3
0
3
0
3
0
3
0
0
0
3
0
0
0
3
0
0
0
3
3
2
3
3
3
1
3
3
70 / / / / / / / /
80 / / / / / / / /
NIL
7
0
0
0
3
0
0
0
3
0
0
0
3
(defun othello (bl-strategy wh-strategy &optional (print t))
(let ((board (initial-board)))
(loop for player = black
then (next-to-play board player print)
for strategy = (if (eql player black)
bl-strategy
wh-strategy)
until (null player)
do (get-move strategy player board print))
(when print
(format t "~&The game is over. Final result:")
(print-board board))
(count-difference black board)))
OTHELLO
8
(defun get-move (strategy player board print)
(when print (print-board board))
(let ((move (funcall strategy player (copy-board board))))
(cond
((eq move 0)
(progn
(format t "~& abort ")
(abort)))
((and (valid-p move) (legal-p move player board))
(when print
(format t "~&~c moves to ~d." (name-of player) move))
(make-move move player board))
(t (warn "Illegal move: ~d" move)
(get-move strategy player board print)))))
GET-MOVE
9
(defun next-to-play (board previous-player print)
(let ((opp (opponent previous-player)))
(cond ((any-legal-move? opp board) opp)
((any-legal-move? previous-player board)
(when print
(format t "~&~c has no moves and must pass." (name-of opp)))
previous-player)
(t nil))))
NEXT-TO-PLAY
(next-to-play (initial-board) white t)
1
(defun any-legal-move? (player board)
(some #'(lambda (move) (legal-p move player board))
all-squares))
ANY-LEGAL-MOVE?
(any-legal-move? black (initial-board))
54
(defun human (player board)
(declare (ignore board))
(format t "~&~c to move: " (name-of player))
(first (read)))
HUMAN
(human black (initial-board))
@ to move: (56)
(56)
10
Two people play against each other
@ to move: (56)
@ moves to 56.
(othello #'human #'human))
1 2 3 4 5 6 7 8
[@=2
0=2
(0)]
10 / / / / / / / /
50 / / / @ @ @ / /
60 / / / / / / / /
60 / / / / / / / /
70 / / / / / / / /
70 / / / / / / / /
80 / / / / / / / /
80 / / / / / / / /
@ to move: (57)
0 to move: (64)
;;; Warning: Illegal move: 57
40 / / / 0 @ / / /
50 / / / @ 0 / / /
60 / / / / / / / /
70 / / / / / / / /
80 / / / / / / / /
0=3
40 / / / 0 @ / / /
50 / / / @ 0 / / /
30 / / / / / / / /
[@=3
(+3)]
30 / / / / / / / /
40 / / / 0 @ / / /
20 / / / / / / / /
0=1
20 / / / / / / / /
30 / / / / / / / /
10 / / / / / / / /
[@=4
10 / / / / / / / /
20 / / / / / / / /
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
[@=2
0=2
(0)]
0 moves to 64.
1 2 3 4 5 6 7 8
10 / / / / / / / /
20 / / / / / / / /
30 / / / / / / / /
40 / / / 0 @ / / /
50 / / / 0 @ @ / /
60 / / / 0 / / / /
70 / / / / / / / /
80 / / / / / / / /
11
(0)]
Exercise Problems
If you have time, try to do the following
exercise problems.
1. Understand examples in lecture notes.
2. Can you make a random strategy function so that a
human plays again computer that uses the random
strategy.
3. Can you make a (8 x 8)Tic Tac Toe game that two
human players can play.
12
Download