There are a number of different GDL representations of Tic-Tac-Toe out in the wild. For this exercise, I've chosen the one that's seen the most use lately, Tiltyard's Tic-Tac-Toe. I've taken some liberties with rearranging the rules and improving the formatting, but the rules themselves are untouched. GDL keywords and language features (aside from the <= operator) are in bold. Enjoy!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Tictactoe ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Roles ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; There are two roles to be assigned to players in tic-tac-toe: one that plays ; X marks and one that plays O marks. The ordering that we list these roles is ; important to the GDL communication protocol, but has no impact on the rules ; of the game; turn ordering, for example, is defined later. As a game author, ; we could swap these two statements to no effect. (role xplayer) (role oplayer) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Initial State ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; In the initial state of the game, each cell of the game board is blank, and ; xplayer is about to move. (Note that "cell" and "control" don't have intrinsic ; meaning in GDL; their meaning comes from how they affect the game in rules ; below.) (init (cell 1 1 b)) (init (cell 1 2 b)) (init (cell 1 3 b)) (init (cell 2 1 b)) (init (cell 2 2 b)) (init (cell 2 3 b)) (init (cell 3 1 b)) (init (cell 3 2 b)) (init (cell 3 3 b)) (init (control xplayer)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Dynamic Components ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If the cell (x, y) is blank, and it's a player's turn, then that player may ; play the move "(mark x y)", which represents drawing their mark in the cell ; (x, y). x and y are variables, so actual examples of moves will look like ; (mark 1 1), (mark 2 3), and so on. (<= (legal ?w (mark ?x ?y)) (true (cell ?x ?y b)) (true (control ?w))) ; If it's oplayer's turn, then xplayer can make a noop move. (Noop comes from the ; phrase "no operation" from assembly language, so a noop move does nothing. Games ; are required to give each player at least one possible move each turn, so players ; with nothing to do are given noop moves.) (<= (legal xplayer noop) (true (control oplayer))) ; If it's xplayer's turn, then oplayer can make a noop move. (<= (legal oplayer noop) (true (control xplayer))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Cell ; If xplayer takes the action (mark m n), and the cell (m, n) is blank this turn, ; then next turn the cell (m, n) will contain an X. (<= (next (cell ?m ?n x)) (does xplayer (mark ?m ?n)) (true (cell ?m ?n b))) ; If oplayer takes the action (mark m n), and the cell (m, n) is blank this turn, ; then next turn the cell (m, n) will contain an O. (<= (next (cell ?m ?n o)) (does oplayer (mark ?m ?n)) (true (cell ?m ?n b))) ; If the cell (m, n) has a mark w in it this turn, and the mark is not "blank", ; the same mark will still be in cell (m, n) next turn. (<= (next (cell ?m ?n ?w)) (true (cell ?m ?n ?w)) (distinct ?w b)) ; If either player takes the action (mark j k) to mark the cell (j, k), and the ; cell (m, n) is blank this turn, and the two cells are different (either m != j ; or n != k), then next turn (m, n) will still be blank. (<= (next (cell ?m ?n b)) (does ?w (mark ?j ?k)) (true (cell ?m ?n b)) (or (distinct ?m ?j) (distinct ?n ?k))) ; If this turn oplayer was in control, then next turn xplayer will be in control. (<= (next (control xplayer)) (true (control oplayer))) ; If this turn xplayer was in control, then next turn oplayer will be in control. (<= (next (control oplayer)) (true (control xplayer))) ; If the cells (m, 1), (m, 2), and (m, 3) all contain the same mark, then we say ; there's a row of that mark at row m. (<= (row ?m ?x) (true (cell ?m 1 ?x)) (true (cell ?m 2 ?x)) (true (cell ?m 3 ?x))) ; If the cells (1, n), (2, n), and (3, n) all contain the same mark, then we say ; there's a column of that mark at column n. (<= (column ?n ?x) (true (cell 1 ?n ?x)) (true (cell 2 ?n ?x)) (true (cell 3 ?n ?x))) ; If the cells (1, 1), (2, 2), and (3, 3) all contain the same mark, then we say ; there's a diagonal with that mark. (<= (diagonal ?x) (true (cell 1 1 ?x)) (true (cell 2 2 ?x)) (true (cell 3 3 ?x))) ; If the cells (1, 3), (2, 2), and (3, 1) all contain the same mark, then we say ; there's a diagonal with that mark. (<= (diagonal ?x) (true (cell 1 3 ?x)) (true (cell 2 2 ?x)) (true (cell 3 1 ?x))) ; If there's a row, column, or diagonal with a mark, then we say there's a line ; with that mark. (<= (line ?x) (row ?m ?x)) (<= (line ?x) (column ?m ?x)) (<= (line ?x) (diagonal ?x)) ; If there's some cell (m, n) on the board that's blank this turn, then we say ; the board is open. (<= open (true (cell ?m ?n b))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If there's a line of X marks, then xplayer gets a score of 100 (win). (<= (goal xplayer 100) (line x)) ; If the board is not open and there is neither a line of Xs nor a line of Os, ; then xplayer gets a score of 50 (draw). (<= (goal xplayer 50) (not (line x)) (not (line o)) (not open)) ; If there's a line of O marks, then xplayer gets a score of 0 (loss). (<= (goal xplayer 0) (line o)) ; If there's a line of O marks, then oplayer gets a score of 100 (win). (<= (goal oplayer 100) (line o)) ; If the board is not open and there is neither a line of Xs nor a line of Os, ; then oplayer gets a score of 50 (draw). (<= (goal oplayer 50) (not (line x)) (not (line o)) (not open)) ; If there's a line of X marks, then oplayer gets a score of 0 (loss). (<= (goal oplayer 0) (line x)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; If there's a line of X marks or a line of O marks, the game is over. (<= terminal (line x)) (<= terminal (line o)) ; If the board is not open, the game is over. (<= terminal (not open)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Base & Input ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; This is an optional part of the game description listing all the types of things ; that can be part of the state of the game on some turn of the game. These rules ; have no effect on the game rules, but some gamers can take advantage of definitions ; like these. ; Note that we only list things that are part of the game state: things that are ; defined using "init" and "next" and referenced using "true". Things that are ; logical consequences of the state, such as "row", "line", and "open", don't get ; listed here. ; 1, 2, and 3 are possible indices of spaces on the game board. We define "index" here ; as a constant set of possibilities that we can reference elsewhere in the game ; description. (index 1) (index 2) (index 3) ; Here we take advantage of the indices listed above to quickly define a set of true ; statements. (We could have done the same when defining the cells that are initially ; blank.) ; A cell (x, y) can be blank, for any valid index x and any valid index y. (<= (base (cell ?x ?y b)) (index ?x) (index ?y)) ; A cell (x, y) can have an x mark or an o mark, for any valid index x and any valid ; index y. (<= (base (cell ?x ?y x)) (index ?x) (index ?y)) (<= (base (cell ?x ?y o)) (index ?x) (index ?y)) ; For each role, it may be that role's turn. (<= (base (control ?p)) (role ?p)) ; This is another optional part of the game description. Where "base" relations dealt ; with states of the game, "input" relations deal with possible moves. ; For any role, it is possible for that role to play (mark x y) for any valid ; index x and any valid index y. (<= (input ?p (mark ?x ?y)) (index ?x) (index ?y) (role ?p)) ; For any role, it is possible for that role to play the noop move. (<= (input ?p noop) (role ?p))
No comments:
Post a Comment