# A simple Noughts and Crosses (Tic Tac Toe) game. # This is to demonstrate that Avios isn't simply for standard server stuff. # A simple networked game like this wouldn't be worth the effort of writing # in C but in Avios its simple, just give it a port to run on in the init file. &stdalias.inc var @board pcnt cwon pwon var @winlines @order @pieces set winlines "123 456 789 147 258 369 159 357" set order "5 1 3 7 9 2 4 6 8" set pieces:"1" "..~FT00~RS.. .~FGX~RS..~FGX~RS." set pieces:"2" ".~FTO~RS..~FTO~RS. ..~FGXX~RS.." set pieces:"3" ".~FTO~RS..~FTO~RS. ..~FGXX~RS.." set pieces:"4" "..~FTOO~RS.. .~FGX~RS..~FGX~RS." #--- Main procedure contains main loop proc main while TRUE set board ". . . . . . . . ." set pcnt 0 set cwon 0 set pwon 0 print [format "\n\n~BM-=-=-=*{ Noughts & Crosses }*=-=-=-\n\n"] # Computer goes first depending on rand if [rand 1] printnl "~FGI'll start..." set board#5 "X"; inc pcnt else printnl "~FTYou start..." endif # Mainloop call display_board while TRUE call player_move call end_game if $result; break; endif call computer_move call display_board call end_game if $result; break; endif wend wend endproc #--- Display the board --- proc display_board var h i j el # Go through positions for h 1 to 7 step 3 # Go through pieces array for i 1 to 4 # Go through positions on line for j h to [math h+2] if board#j="O"; print [elements pieces#i 1]; endif if board#j="X"; print [elements pieces#i 2]; endif if board#j="." if i=2; print [format "..~OL%d~RS..." j] else; print "......"; endif endif next printnl next next printnl endproc #--- Get input from player --- proc player_move var pos while TRUE print "~FTMove> "; input pos if pos=""; continue; endif if [not [isnum pos]] or pos<1 or pos>9 printnl "~FR~OLIllegal input."; continue endif if board#pos!="." printnl "~FR~OLPosition is occupied."; continue endif break; wend set board#pos "O" inc pcnt call display_board call check_player_win endproc #--- Computers turn --- proc computer_move var piece i s line a b c pos # See if computer can win on next move then see if player can set piece "X" inc pcnt for i 1 to 2 foreach s line in winlines set a [midstr line 1] set b [midstr line 2] set c [midstr line 3] if board#a="." and board#b=piece and board#c=piece call place_piece a if piece="O"; return; endif inc cwon return endif if board#a=piece and board#b="." and board#c=piece call place_piece b if piece="O"; return; endif inc cwon return endif if board#a=piece and board#b=piece and board#c="." call place_piece c if piece="O"; return; endif inc cwon return endif nexteach set piece "O" next # Look to create a pair foreach s line in winlines set a [midstr line 1] set b [midstr line 2] set c [midstr line 3] if board#a="X" and board#b="." and board#c="." call place_piece c; return endif if board#a="." and board#b="X" and board#c="." call place_piece a; return endif if board#a="." and board#b="." and board#c="X" call place_piece a; return endif nexteach # Pick first free spot in a certain order foreach s pos in order if board#pos="." call place_piece pos; return endif nexteach endproc #--- Place a piece for the computer --- proc place_piece pos set board:pos "X" print [format "~FGMy move: ~FM%s\n\n" pos] endproc #--- See if player has won --- proc check_player_win var s line a b c foreach s line in winlines set a [midstr line 1] set b [midstr line 2] set c [midstr line 3] if board#a="O" and board#b="O" and board#c="O" inc pwon; return endif nexteach endproc #-- Display result and prompt for new game --- proc end_game var inp if pwon; print [format "\n~FT~LI*** YOU WIN ***\n\n"] else if cwon; print [format "\n~FG~LI*** I WIN ***\n\n"] else if pcnt=9; print [format "\n~FY*** GAME DRAWN ***\n\n"] else; return 0; endif endif endif print "Would you like another game? (y/n): " input inp if inp="y" or inp="Y"; return 1; endif print [format "\n~LIOk, goodbye then...\n\n"] exit 0 endproc