  rem -- Tic Tac Toe game by Mac --

  OPTION SCALE, 96
  TITLE By Mac
  DIALOG CREATE,Tic Tac Toe,-1,0,200,280
  DIALOG ADD,STYLE,Style1,,,,BLACK
  DIALOG ADD,STYLE,Style2,Arial,32,BC,BACKGROUND,LTBLUE
  DIALOG ADD,STYLE,Style3,Arial,12,BC,BLACK,LTGREEN
  DIALOG ADD,STYLE,Style4,,,,WHITE

  DIALOG ADD,RADIO,Player,10,5,80,60," Plays First ",Computer|Player,"Player"
  DIALOG ADD,BUTTON,NewGame,15,90,105,25,"Start New Game"

  DIALOG ADD,TEXT,SignFrame,46,90,105,24,"",Style4
  DIALOG ADD,TEXT,Sign,48,92,101,20,"",Style3

  DIALOG ADD,TEXT,HLine1,150,21,158,4,"",Style1
  DIALOG ADD,TEXT,HLine2,204,21,158,4,"",Style1
  DIALOG ADD,TEXT,VLine1,100,71,4,158,"",Style1
  DIALOG ADD,TEXT,VLine2,100,125,4,158,"",Style1

  DIALOG ADD,TEXT,S1,100,21,50,50,"",CLICK,Style2
  DIALOG ADD,TEXT,S2,100,75,50,50,"",CLICK,Style2
  DIALOG ADD,TEXT,S3,100,129,50,50,"",CLICK,Style2
  DIALOG ADD,TEXT,S4,154,21,50,50,"",CLICK,Style2
  DIALOG ADD,TEXT,S5,154,75,50,50,"",CLICK,Style2
  DIALOG ADD,TEXT,S6,154,129,50,50,"",CLICK,Style2
  DIALOG ADD,TEXT,S7,208,21,50,50,"",CLICK,Style2
  DIALOG ADD,TEXT,S8,208,75,50,50,"",CLICK,Style2
  DIALOG ADD,TEXT,S9,208,129,50,50,"",CLICK,Style2
  DIALOG SHOW

  rem -- Load combinations for computer playing to win or block --
  rem -- Item 0-15 = 2 adjacent squares occupied (of 3 in a row) --
  rem -- Item 16-23 = 2 squares on each end occupied (of 3 in a row) --
  rem -- Item 24-35 = avoid bi-directional traps --
  LIST CREATE, 1
  LIST LOADTEXT, 1,
"7|4|1
"9|5|1
"3|2|1
"8|5|2
"1|2|3
"7|5|3
"6|9|3
"6|5|4
"4|5|6
"1|4|7
"3|5|7
"9|8|7
"2|5|8
"7|8|9
"1|5|9
"3|6|9
"1|3|2
"4|6|5
"7|9|8
"1|7|4
"2|8|5
"3|9|6
"1|9|5
"7|3|5
"2|4|1
"2|6|3
"8|4|7
"8|6|9
"1|6|8
"1|8|6
"3|8|4
"3|4|8
"9|4|2
"9|2|4
"7|2|6
"7|6|2

:NewGameBUTTON
  DIALOG SET, Sign, "You are X"
  %%winner = ""
  %x = 1
  REPEAT 
    DIALOG SET, S%x, ""
    %x = @succ(%x)
  UNTIL @greater(%x, 9)
  if @equal(@dlgtext(Player), "Computer")
    goto Computer
  end 
:EVLOOP
  WAIT EVENT
  %e = @event()
  if %%winner
    if @equal(@substr(%e,1),"S")
      goto EVLOOP
    end 
  end 
  goto %e

:S1CLICK
:S2CLICK
:S3CLICK
:S4CLICK
:S5CLICK
:S6CLICK
:S7CLICK
:S8CLICK
:S9CLICK
  %s = @substr(%e,1,2)
  if @not(@dlgtext(%s))
    DIALOG SET, %s, "X"
    %%player = 1
    goto CheckStatus
  else 
    INFO There's an  @dlgtext(%s)  in that square!@tab()
  end 
  goto EVLOOP

:Computer
  rem -- Wait to give appearance of computer thinking --
  DIALOG SET, Sign, "Thinking"
  WAIT 
  %%player = ""
  %%square = ""
  rem -- Check for computer to win. If not, try to block player --
  %p = "O"
  :LOOP1 
  %x = 0
  REPEAT 
    PARSE "%a;%b;%c", @item(1, %x)
    if @both(@equal(@dlgtext(S%a), %p), @equal(@dlgtext(S%b), %p))
      if @not(@dlgtext(S%c))
        %%square = S%c
      end 
    end 
    %x = @succ(%x)
  UNTIL @equal(%x, @count(1))%%square
  if %%square
    goto Play
  else 
    if @equal(%p, "O")
      %p = "X"
      goto LOOP1
    end 
  end 
  rem -- If can't win or block, try to set up a win (sort of) --
  %x = 0
  REPEAT 
    PARSE "%a;%b;%c", @item(1, %x)
    if @both(@equal(@dlgtext(S%a), "O"), @not(@dlgtext(S%c)))
      if @not(@dlgtext(S%b))
        %%square = S%b
      end 
    end 
    %x = @succ(%x)
  UNTIL @equal(%x, @count(1))%%square
  if %%square
    goto Play
  end 
  rem -- Low on strategic options, try for center square --
  if @not(@dlgtext(S5))
    %%square = S5
    goto Play
  end 
  rem -- No strategy left, randomly pick an open square --
  REPEAT 
    rem -- Use last digit of @datetime() as random number --
    %r = @datetime()
    %r = @substr(%r, @len(%r))
    rem -- Make sure it's 1 to 9 --
    if @greater(1, %r)
      %r = 5
    end 
    if @not(@dlgtext(S%r))
      %%square = S%r
    end 
  UNTIL %%square
  goto Play

:Play
  DIALOG SET, %%square, "O"
:CheckStatus
  rem -- Check horizontal win --
  %x = 1
  REPEAT 
    %a = %x
    %b = @sum(%x, 1)
    %c = @sum(%x, 2)
    GOSUB Check3
    %x = @sum(%x, 3)
  UNTIL @greater(%x, 7)
  rem -- Check vertical win --
  %x = 1
  REPEAT 
    %a = %x
    %b = @sum(%x, 3)
    %c = @sum(%x, 6)
    GOSUB Check3
    %x = @succ(%x)
  UNTIL @greater(%x, 3)
  rem -- Check diagonal win --
  %a = 1
  %b = 5
  %c = 9
  GOSUB Check3
  %a = 3
  %c = 7
  GOSUB Check3
  if %%winner
    rem -- Let computer whine a little --
    if @equal(@dlgtext(Player), "Player")
      if @equal(%%winner, "You")
        WAIT 
        if @ask(You Won.@cr()@cr()Can computer go first now?@tab())
          DIALOG SET, Player, "Computer"
          goto NewGameBUTTON
        end 
      end 
    end 
    goto EVLOOP
  end 
  GOSUB CanPlay?
  if @not(%%OK)  
    DIALOG SET, Sign, "No Winner"
    goto EVLOOP
  end 
  if %%player
    goto Computer
  end 
  DIALOG SET, Sign, "Your Move"
  goto EVLOOP

:CLOSE
  EXIT 

  rem ----------- GOSUB ROUTINES ------------

:CanPlay?
  %%OK = ""
  rem -- Check if any moves left --
  %x = 1
  REPEAT 
    if @not(@dlgtext(S%x))
      %%OK = 1
    end 
    %x = @succ(%x)
  UNTIL @greater(%x, 9)
  exit 

:Check3
  rem -- Check for 3 in a row --
  if @dlgtext(S%a)
    if @both(@equal(@dlgtext(S%a), @dlgtext(S%b)), @equal(@dlgtext(S%b), @dlgtext(S%c)))
      if @equal(@dlgtext(S%a), "X")
        DIALOG SET, Sign, "You Won!"
        %%winner = "You"
      else 
        %%winner = "Computer"
        DIALOG SET, Sign, "You Lost..."
      end 
    end 
  end 
  exit 
