Script Library: 1213 scripts
 

tictactoe.r

REBOL [ Title: "Tic Tac Toe" Date: 27-Dec-2001/11:50:39-8:00 Version: 1.0.3 File: %tictactoe.r Author: "Ryan S. Cole" Purpose: "No known purpose." History: [ 23-Oct-2001 "Made things more colorful." 27-Dec-2001 "Fixed bug allowing win condition." 27-Dec-2001/11:50:39-8:00 "Now works properly with View or Link." ] Email: %ryancole--usa--com Comments: {Special thanks to Larry Snyder for help in simplifying game logic.} library: [ level: 'intermediate platform: 'all type: [Demo Game] domain: [VID graphics] tested-under: none support: none license: none see-also: none ] ] ;;;;;;;;;;;;;;;;; ;;; game data ;;; ;;;;;;;;;;;;;;;;; ; represents the 9 positions available game-grid: " " ; 9 spaces ; the winning mark combinations win-table: [ "mmm??????" "???mmm???" "??????mmm" "m??m??m??" "?m??m??m?" "??m??m??m" "m???m???m" "??m?m?m??" ] ;;;;;;;;;;;;;;;;;;;;;;;; ;;; helper functions ;;; ;;;;;;;;;;;;;;;;;;;;;;;; ; returns opposing players marker other: func [m [char!]][either m = #"X" [#"O"][#"X"]] ; tests for a winning condition for a particular marker win?: function [grid mark] [tmp-grid] [ replace/all tmp-grid: copy grid mark #"m" foreach win win-table [ if found? find/any tmp-grid win [return yes] ] ] ;;;;;;;;;;;;;;;;;; ;;; game logic ;;; ;;;;;;;;;;;;;;;;;; ; returns the best move get-win-move: function [grid mark] [move] [ if grid/5 = #" " [return poke grid 5 mark] if move: win-move? grid mark [return poke grid move mark] if move: win-move? grid other mark [return poke grid move mark] if grid/5 = mark and any [ (grid/1 = grid/9) and (grid/1 = other mark) (grid/3 = grid/7) and (grid/3 = other mark) ] [ return poke grid 4 mark ] either (grid/6 = other mark) or (grid/8 = other mark) [ if grid/9 = #" " [return poke grid 9 mark] if grid/7 = #" " [return poke grid 7 mark] if grid/3 = #" " [return poke grid 3 mark] if grid/1 = #" " [return poke grid 1 mark] ] [ if grid/1 = #" " [return poke grid 1 mark] if grid/3 = #" " [return poke grid 3 mark] if grid/7 = #" " [return poke grid 7 mark] if grid/9 = #" " [return poke grid 9 mark] ] replace grid #" " mark ] ; tries to return the move that would ; result an immediate win for a given marker win-move?: func [grid mark] [ repeat idx 9 [ if grid/:idx = #" " [ if win? poke copy grid idx mark mark [return idx] ] ] ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; game control and visual ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; creates a layout for the screen lay-grid: does [ lay: copy [ backdrop white effect [merge gradcol 1x1 255.0.0 0.0.255] origin 0x0 space 3x3 style square box 30x30 ivory font [color: red shadow: none] ] repeat idx length? game-grid [ repend lay [ 'square to-string game-grid/:idx ] if game-grid/:idx = #"O" [ append lay [font [color: blue] ] ] if game-grid/:idx = #" " [ repend/only lay ['react-to-move idx] ] if zero? idx // 3 [append lay 'return] ] append lay [at 0x0 message: label 0x0 center font-size 26] ] ; reacts to users input when a space is pressed react-to-move: func [index] [ poke game-grid index #"X" check-state game-grid: get-win-move game-grid #"O" check-state ] ; checks for a lose or tie and updates screen check-state: does [ if win? game-grid #"O" [clear-game "YOU^/LOSE!"] if not found? find game-grid #" " [clear-game "TIE^/GAME!"] refresh ] ; Clears the game board with special effects. Clear-game: function [msg] [color] [ refresh message/text: msg message/size: 100x100 message/effect: copy [] color: 255.0.0 loop 16 [ message/font/color: color: color - 16.0.0 + 0.0.16 append message/effect [merge blur] show main-face wait .2 ] game-grid: copy " " ] ; repaints the screen refresh: does [ main-face/pane: layout/offset lay-grid 0x0 show main-face ] ;;;;;;;;;;;;;;;;;;;;;;; ;;; start game play ;;; ;;;;;;;;;;;;;;;;;;;;;;; main-face: view/new layout lay-grid do-events
halt ;; to terminate script if DO'ne from webpage
Notes
  • email address(es) have been munged to protect them from spam harvesters. If you are a Library member, you can log on and view this script without the munging.
  • (ryancole:usa:com)