View in color | License | Download script | History | Other scripts by: skurunner |
30-Apr 14:43 UTC
[0.049] 14.176k
[0.049] 14.176k
tictactoe.rREBOL [
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 Notes
|