Skip to content

An Internet Extension to 3D Noughts and Crosses

Vector 12:4, page 119

system interfaces competitions and puzzles

Transcribed from the printed issue; not yet reviewed. Read it in the PDF of the issue, page 119

Introduction

The competition announced in Vector 12.3 depicted a situation, where instead of me playing against one of my children sitting next to me, the PC could be the opponent - probably annoyingly skilled, always concentrating, never failing to take advantage of my mistakes. Although the programming task sounded like a challenge, I wanted to approach the problem in a different way by enabling two people, both using their own PCs, to play against each other via the Internet.

Duncan Pearson’s original game is based on three events. The Internet extension needs a fourth event and some additional steps into the original three (all enhancements are marked with italics) to be introduced:

  • New Game (a menu event) initialises the variables, draws the grid and gives the turn to the red (i.e. the client).
  • Place (a mouse event) converts the mouse co-ordinates into the ball index (0 to ¯1+n*3), sends the ball index to the other player, checks for a win and switches to the other player’s colour.
  • Spin (a keyboard event) rotates the grid; no change - both players may spin their grids independently and do not know about their opponent’s viewing angle.
  • Receive (TCP/IP event) takes place when the other player has placed a ball. The Place event is then created, with the exception that since the ball index is already known, the conversion from mouse co-ordinates is skipped.

Communication Protocol

The TCP/IP protocol, which creates the connection between the two players and sends the ball index after every move, is built using AP119/W by Lingo Allegro, Inc. (see review on page 38). The event-driven approach to TCP/IP programming is particularly useful in an application like the 3D Noughts and Crosses, which is inherently event-driven.

The first player selects the menu item New (as Internet Server). AP119/W creates a listening socket and waits for "clients". Nothing else happens until the second player selects the menu item New (as Internet Client), and is prompted for the server’s IP address. A socket with a connection to our not-so-well-known port number 3333 is established, and the game starts with the client’s turn to place the first ball. The socket remains open to the end of the game.

Each placement of a new ball is communicated to the other player with the TCP/IP SEND command, detected by the READ event on the other side. When either player has won, the socket is closed and the server is free to play with other clients.

Changes to Duncan’s Original APL Code

Only three essential changes to the programs listed in Vector 12.3 were required:

  1. Two new menu items allow for starting the game as a server or a client:
Make[28-29]

'form.menu.game.new2'⎕WC'menuitem'
    'New (as Internet &Server)'
    ('event' 'Select' '⍎colour[]←0 ⋄ Connect 1 ⋄ Draw')

'form.menu.game.new3'⎕WC'menuitem'
    'New (as Internet &Client)'
    ('event' 'Select' '⍎colour[]←0 ⋄ Connect 0 ⋄ Draw')
  1. If the ball index is received from the other player, the code that handles mouse co-ordinates is skipped:
Place[11]
→Lb1/⍨hismove←0=≡hit←msg
  1. The player’s own move has to be communicated to the opponent:
Place[24-26]
Lb1:

 →0/⍨×colour[hit]

 Message hismove↓hit

Other Issues

Since there is, apart from yourself, nobody around to say "Wake up, it’s your turn", I recorded two .wav files yourturn.wav and plsewait.wav (the names are self-descriptive), one of which is played after a move took place. I modified the standard PLAY program to replay the last sound file every 30 seconds to simulate a real-life situation where intensive thinking is interrupted by a reminder "Come on, it’s your turn".

I also took advantage of the open socket and allowed the players to send comments to each other. Whenever a character string, which clearly is not a ball index, is transmitted, it is simply displayed in the APL session.

Cheating is possible as it is in real life. There is nothing to prevent you from placing a ball on the other player’s turn. However, if you have a sound board and the speakers are on, you will hear that something went wrong.

Conclusion

Of all client/server applications that I have designed, this one demonstrates the most literal participation from the server. A crucial difference with a single-PC, two-player game is that once the grid gets populated, it is increasingly difficult to see where the opponent placed the new ball - it may pop up just as you are looking elsewhere.

Networked 3D Noughts and Crosses can be played at APL96, and the complete workspace can be downloaded from http://www.demon.co.uk/apl385. (But you need to have AP119/W rel 2.0 in order to play the game.)

Program Listings

The TCPxxx programs are not listed here.

 Connect n;a
⍝Start game as a client (n=0) or a server (n=1)
⍝Timo Laurmaa 23.2.1996
 →n/Lb2                                         ⍝ Jump if server
⍝Playing as a client
 ⍎(0=⎕NC'IPADR')/'IPADR←''X.X.X.X'''            ⍝ Initial IP address mask
Lb1:IPADR←IPADR Win_input'IP address of server' ⍝ Prompt for server's IP address
 →0/⍨0∊⍴IPADR←' '~⍨IPADR                        ⍝ Quit if nothing entered
 →Lb1/⍨'X'∊IPADR                                ⍝ Jump if clearly wrong input
 a←0 TCPSOCKET IPADR 3333 'ThreeD'              ⍝ Port 3333, protocol ThreeD
 a←PLAY'YourTurn.wav'                           ⍝ Client starts always
 →0
Lb2:a←PLAY'PlseWait.wav'                        ⍝ Wait until a client joins
 →Lb3/⍨Mode=0                                   ⍝ Jump if single PC so far
 →0/⍨(⊂'ThreeD')∊PROTOCOLS                      ⍝ Exit if already waiting/playing
Lb3:a←1 TCPSOCKET'0.0.0.0' 3333 'ThreeD'        ⍝ Wait for clients
Message v;n;s
⍝Tell the other player what your move was
⍝Timo Laurmaa 23.2.1996
 →Lb1/⍨0∊⍴v                               ⍝ Jump if he moved
 →0/⍨Mode=0                               ⍝ Exit if single PC mode
 s←((⌽PROTOCOLS)⍳⊂'ThreeD')⊃⌽SOCKETS      ⍝ The last "3D" socket is for sending
 a←s TCPSEND'N'(⍕v)                       ⍝ Send without conversion
 a←PLAY'PlseWait.wav'                     ⍝ Now waiting for his move
 →0
Lb1:a←PLAY'YourTurn.wav'                  ⍝ Your turn.
 ThreeD V;EV;SN;VAR;T
⍝ 3-D Noughts and crosses TCP/IP event handler
 (EV SN)←V                                  ⍝ Event nr, socket
 →1 (EV=1 32)/READ CLOSE                    ⍝ Select the event
READ:A←TCP'RECV'SN 0 'N'                    ⍝ Read without translation
 →MOVE/⍨(1 2∨.=⍴A)∧∧/A∊'1234567890'         ⍝ Other player's move: n or nn
 ⍎('⍎'≠1↑A)/'⎕←A ⋄ →0'                      ⍝ Display if not to be executed
 Exe 1↓A ⋄ →0                               ⍝ Execute with error trapping
MOVE:TCPINFO'The other player''s move: ',A  ⍝ Write log info about the move
 Place⍎A ⋄ →0                               ⍝ Call Noughts and Crosses, exit
CLOSE:colour[]←0 ⋄ Draw                     ⍝ Initialise game if socket lost
 z←Mode;L;SN
⍝Indicated whether the game is played in a single-PC, Server or Client Mode
⍝z ↔ 0 (Single-PC) or 1 (Client) or 2 (Server, playing) or 3 (Server, waiting)
⍝Timo Laurmaa 3.3.1996
 z←0                                      ⍝ Default: Single PC
 →0/⍨(0=⎕NC'SOCKETS')∨2≠⎕SVO'TcpIp'       ⍝ Exit if single PC mode
 →0/⍨1≠z←2⌊+/L←PROTOCOLS≡¨⊂'ThreeD'       ⍝ How many "3D" sockets open
 SN←SOCKETS[L⍳1]
 z←z+2×1 0≡2 ∊1⊃TCP'SELECT'SN SN SN ¯1    ⍝ Return 3 if only listening socket open