$! ------------------ CUT HERE ----------------------- $ v='f$verify(f$trnlnm("SHARE_VERIFY"))' $! $! This archive created by VMS_SHARE Version 7.2-007 22-FEB-1990 $! On 7-APR-1993 18:58:18.88 By user MASTER $! $! This VMS_SHARE Written by: $! Andy Harper, Kings College London UK $! $! Acknowledgements to: $! James Gray - Original VMS_SHARE $! Michael Bednarek - Original Concept and implementation $! $!+ THIS PACKAGE DISTRIBUTED IN 5 PARTS, TO KEEP EACH PART $! BELOW 30 BLOCKS $! $! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER $! AND EXECUTE AS A COMMAND PROCEDURE ( @name ) $! $! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING: $! 1. BUILD.COM;1 $! 2. SNAKE.MAR;1 $! 3. SNAKE.SCN;1 $! 4. SNAKEH.FOR;1 $! 5. SNAKEP.PAS;1 $! $set="set" $set symbol/scope=(nolocal,noglobal) $f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID")) $e="write sys$error ""%UNPACK"", " $w="write sys$output ""%UNPACK"", " $ if f$trnlnm("SHARE_LOG") then $ w = "!" $ ve=f$getsyi("version") $ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START $ e "-E-OLDVER, Must run at least VMS 4.4" $ v=f$verify(v) $ exit 44 $UNPACK: SUBROUTINE ! P1=filename, P2=checksum $ if f$search(P1) .eqs. "" then $ goto file_absent $ e "-W-EXISTS, File ''P1' exists. Skipped." $ delete 'f'* $ exit $file_absent: $ if f$parse(P1) .nes. "" then $ goto dirok $ dn=f$parse(P1,,,"DIRECTORY") $ w "-I-CREDIR, Creating directory ''dn'." $ create/dir 'dn' $ if $status then $ goto dirok $ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped." $ delete 'f'* $ exit $dirok: $ w "-I-PROCESS, Processing file ''P1'." $ if .not. f$verify() then $ define/user sys$output nl: $ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1' PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET( SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:= CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b)); LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION( BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1); IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE; MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1; ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")= 1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF"; POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r); ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1; COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE, "output_file"));ENDPROCEDURE;Unpacker;QUIT; $ delete/nolog 'f'* $ CHECKSUM 'P1' $ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT $ e "-E-CHKSMFAIL, Checksum of ''P1' failed." $ ENDSUBROUTINE $START: $ create 'f' X$ MACRO SNAKE X$ PASCAL SNAKEP X$ FORTRAN SNAKEH X$! X$ LINK/NOTRACE SNAKE,SNAKEP,SNAKEH,UTIL/LIB X$ DELETE/NOCONFIRM *.OBJ;* X$ EXIT $ CALL UNPACK BUILD.COM;1 1346713570 $ create 'f' X`09.title`09SNAKEM`09Snake Game X;+ X;`09or`09TANKM`09Tank Game X;`09if $$TANK is defined X;- X X`09$dibdef X`09$iodef X`09$qiodef X`09$secdef X`09$jpidef X;`09$ssdef Xesc`09`09= 27 X Xsnake`09`09= 8`09`09; number of snakes X X;`09meaning of event flags in cluster 2 X Xflag$v_master`09= 0`09`09; set if a master snake exists Xflag$v_read`09= 1`09`09; set if all snakes should read command Xflag$v_update`09= 2`09`09; set if all snakes should update screen Xflag$v_game`09= 3`09`09; set if game is in progress Xflag$v_endofgame= 4`09`09; set if we have reached the end of the game Xflag$v_synch`09= 5 Xflag$v_done`09= 8`09`09; set if operation (read,update) is complete X Xcheck_timer`09= 13`09`09; check timer id X X X`09.psect`09$rodata`09nowrt, noexe, shr, pic, long X Xttname_descr: X`09.ascid`09/TT/ X Xmbxcnv: X`09.ascid`09/_MBA!UW:/`09; convert mbx unit number to physical name X Xmbxbuf_descr: X`09.word`09mbxbuf_siz, 0 X`09.long`09mbxbuf X Xdibbuf_descr: X`09.word`09dib$k_length, 0 X`09.long`09dibbuf X X`09.align long Xsnake_desc_2: X.if ndf $$tank X`09.ascid`09/SNAKE_1/`09`09; name of snake event flags X.iff X`09.ascid`09/TANK_1/ X.endc X X`09.align`09long Xsnake_map_name: X.if ndf $$tank X`09.ascid`09/SNAKE_DATA/ X.iff X`09.ascid`09/TANK_DATA/ X.endc X Xtext = . X`09.ascii`09'<'`09`09; enter ANSI mode X`09.ascii`09'(B'`09`09; select ascii character set X`09.ascii`09'`5B2J'`09`09; erase entire screen X`09.ascii`09'`5B1;1H'`09`09; jump to top left corner X`09.ascii`09<10>`09`09`09; linefeed X.if ndf $$tank X`09.ascii`09'#3 SNAKE' ; double-height top half X.iff X`09.ascii`09'#3 TANK' X.endc X`09.ascii`09<13><10> X.if ndf $$tank X`09.ascii`09'#4 SNAKE' ; double-height bottom half X.iff X`09.ascii`09'#4 TANK' X.endc X`09.ascii`09<13><10><10> X`09.ascii`09'#6 Thank you for playing' X`09.ascii`09<13><10><10> Xtext_len = . - text X`09.align`09long Xtext_end_game: X`09.long`092 X`09.long`09text X`09.address 10$ X10$:`09.long`09text_len X Xtext = . X`09.ascii`09<13><10><10> X`09.ascii`09'Game aborted because master ' X.if ndf $$tank X`09.ascii`09'snake' X.iff X`09.ascii`09'tank' X.endc X`09.ascii`09' quitted'<13><10><10> Xtext_len = . - text X`09.align`09long Xtext_abort: X`09.long`092 X`09.long`09text X`09.address 10$ X10$:`09.long`09text_len X Xtext = . X`09.ascii`09 'Y' <31+24> <31+1>`09; col 1, row 24 X`09.ascii`09 'G'`09`09`09; exit graphics X`09.ascii`09<7> ' Please wait for next game ...' X`09.ascii`09 'F'`09`09`09; enter graphics Xtext_len = . - text X`09.align`09long Xtext_wait: X`09.long`092 X`09.long`09text X`09.address 10$ X10$:`09.long`09text_len X X`09.align`09long Xusername_jpi: X`09.word`0912, jpi$_username X`09.address username_buf X`09.address username_siz X`09.long`090 X X`09.align`09long Xstart_wait: X`09.long`09-10000000*5, -1`09`09; wait 5 seconds Xsecond_1: X`09.long`09-10000000*1, -1`09`09; wait 1 second Xsecond_2: X`09.long`09-10000000*2, -1`09`09; wait 2 seconds Xupdate_wait: X`09.long`09-100000*33, -1`09`09; wait 33/100 ths of a second Xcheck_wait: X`09.long`09-10000000*4, -1`09`09; wait 2 seconds for checking Xvalid_move: X`09.long`09`5EB101110100`09`09; valid moves are 2,4,6,8 and 5!! Xstart_direction: X.if ndf $$tank X`09.byte`092, 8, 2, 8, 2, 8, 6, 4`09; initial move directions for snake X.iff X`09.byte`096, 4, 4, 6, 2, 8, 6, 4`09; for tank X.endc X`09.align`09long Xadd_head_par: X`09.long`091`09`09`09; parameter list to Pascal routine X`09.address move`09`09`09; each players move Xupdate_par: X`09.long`092 X`09.address outbuf X`09.address screen_len Xupdate_par2:`09`09`09; if we have died, then there is no head X`09.long`092`09`09; to change to a diamond, so write screen X`09.address screen_buf`09; update directly from global memory. X`09.address screen_len X X`09.psect`09$rwbuf`09wrt, noexe, noshr, pic, page X Xmbxname_len = 16 Xmbxname:`09`09`09; room to hold the physical mbx name X`09.blkb`09mbxname_len Xmbxname_descr: X`09.word`09mbxname_len, 0 X`09.long`09mbxname Xmbxiosb: X`09.long`090,0 Xmbxbuf_siz = 32 Xmbxbuf: X`09.blkb`09mbxbuf_siz X Xdibbuf: X`09.blkb`09dib$k_length X X`09.align`09long Xttiosb: X`09.long`090,0 X Xttbuf_siz = 128 Xttbuf: X`09.blkb`09ttbuf_siz X`09.align`09page Xoutbuf_siz = 512 Xoutbuf:: X`09.blkb`09outbuf_siz X X X;snake_fab: X;.if ndf $$tank X;`09$fab`09fnm=, fop=,- X;`09`09fac=, shr= X;.iff X;`09$fab`09fnm=, fop=,- X;`09`09fac=, shr= X;.endc Xmap_range: X`09.address share_data X`09.address share_data+<512*3> Xret_range: X`09.long`090, 0 X X X`09.psect`09$sharedata wrt, noexe, shr, pic, page Xshare_data: X Xgame_count: X`09.long`09`09`09; count of number of games played Xmaster_flag: X`09.long`09`09`09; = 1 if we are master snake Xabort: X`09.long`09`09`09; = 1 if all snakes should abort Xplayer_bits: X`09.long`09`09`09; bit set if that snake is playing Xplayers: X`09.long`09`09`09; bit set if that snake is reserved Xother_players: X`09.long`09`09`09; used by master snake to wait for other X`09`09`09`09; snakes to indicate operation completed Xmove_count: X`09.long`09`09`09; incremented every move. Used for detecting X`09`09`09`09; other snakes hanging the game Xgame_going: X`09.long`09`09`09; <> 0 if a game is going Xyou_just_died: X`09.long`09`09`09; bit I set if snake I just died Xseed: X`09.long`09`09`09; random number seed Xstart_position: X`09.blkl`09snake`09`09; position of starting (1-8) X; X;`09`095 X; 1`09+---------------+ 3 X;`09`7C`09`09`7C X;`09`7C`09`09`7C X; 7`09`7C`09`09`7C 8 X;`09`7C`09`09`7C X;`09`7C`09`09`7C X; 4`09+---------------+ 2 X;`09`096 X; Xscore: X`09.blkl`09snake`09`09; players' score Xn_games: X`09.blkl`09snake`09`09; # of games each player has played Xwins: X`09.blkl`09snake`09`09; # of wins for each player Xplayer_pos: X`09.blkl`09snake`09`09; starting position of each snake X`09.align`09quad Xmove: X`09.blkb`09snake`09`09; each snakes move Xname_size = 32 Xname: X`09.blkb`09name_size * snake ; each snakes name (32 chars long) X. = . + 512 - < . - share_data > X`09.align`09long Xscreen_len: X`09.long`09`09`09; # chars to be output Xscreen_buf: X`09.blkb`09508`09`09; buffer containing screen update X. = . + <512*4> - < . - share_data > X X X`09.psect`09$rwdata`09wrt, noexe, noshr, pic, long X Xttchan: X`09.word Xmbxchan: X`09.word Xdata_ready: X`09.word Xmaster: X`09.word`09`09`09; = 1 if we are master snake Xcontrol_c_flag: X`09.word`09`09`09; non zero if `5EC typed Xdead: X`09.word`09`09`09; bit I set if snake I just died X`09.align`09long Xcluster_2: X`09.long Xcluster_3: X`09.long Xplayer: X`09.long Xplayer_efn:`09`09`09; my player efn in cluster 2 X`09.long Xcurrent_players: X`09.long Xchars_left:`09`09`09; # of chars left in buffer X`09.long Xchar_pointer: X`09.long`09`09`09; address of next character Xlast_move_count: X`09.long Xusername_buf: X`09.blkb`0912 Xusername_siz: X`09.long X Xoutbuf_qio: X`09$qio`09func=io$_writevblk!io$m_noformat,- X`09`09p1=outbuf Xoutput_qio: X`09$qio`09func=io$_writevblk!io$m_noformat X Xread_qio: X`09$qio`09func=io$_readvblk!io$m_timed!io$m_noecho!io$m_nofiltr,- X`09`09iosb=ttiosb,- X`09`09p1=ttbuf, p2=ttbuf_siz, p3=0`09; wait time = 0 X Xexit_block:`09`09`09; exit handler block X`09.long X`09.address snake_exit X`09.long`091`09`09; 1 argument X`09.address 10$ X10$:`09.long`09`09`09; exit reason X X X`09.psect`09$code`09nowrt, exe, shr, pic X X`09.entry`09- XTTINIT, `5Em<> X;+ X; Create a mailbox. Assign a channel to terminal with an associated mailbox V. X;- X`09$crembx_s`09chan=mbxchan, promsk=#`5ExFF00 X`09bsbw`09`09error X`09$getchn_s`09chan=mbxchan, pribuf=dibbuf_descr X`09bsbw`09`09error X`09$fao_s`09`09ctrstr=mbxcnv, outbuf=mbxname_descr,- X`09`09`09outlen=mbxname_descr, p1=dibbuf+dib$w_unit X`09$assign_s`09devnam=ttname_descr, chan=ttchan, - ; acmode=#`5ExFF00, X`09`09`09mbxnam=mbxname_descr X`09blbc`09r0, 100$ X`09movw`09ttchan, outbuf_qio+qio$_chan`09`09;store channel # X`09movw`09ttchan, output_qio+qio$_chan`09`09;store channel # X`09movw`09ttchan, read_qio+qio$_chan`09`09;store channel # X`09$qiow_s`09func=#io$_setmode!io$m_ctrlcast, chan=ttchan,- X`09`09p1=control_c X`09ret X100$: X`09bsbw`09error X`09ret X X`09.entry`09- XTT1CHAR,`09`5Em<> X`09clrb`09ttbuf X`09$qiow_s`09func=#io$_readvblk!io$m_timed!io$m_noecho!io$m_nofiltr,- X`09`09chan=ttchan, iosb=ttiosb,- X`09`09p1=ttbuf, p2=#1, p3=#0`09; wait time = 0 X`09cvtbl`09ttbuf, r0 X`09cmpb`09r0, #13`09`09`09; is it ? X`09bneq`09100$ X`09clrb`09data_ready X100$:`09ret X XTTREAD:: X`09blbs`09control_c_flag, 10$ X`09tstl`09chars_left`09`09; have we used all characters ? X`09bgtr`0950$`09`09`09; no --> 50$ X`09bbsc`09#0, data_ready, 20$`09; check if input ready X5$:`09mnegl`09#1, r0`09`09`09; no characters read X`09rsb`09`09`09`09; no X10$: X`09clrl`09r0`09`09`09; on `5EC return move 0 = quit X`09rsb X20$: X`09$qiow_g read_qio X`09blbc`09r0, 5$`09`09`09; error X; X;`09$qiow_s`09func=#io$_writevblk,chan=ttchan,-`09; debug write X;`09`09p1=ttbuf, p2=ttiosb+2, p4=#`5Ex1000 X X`09movzwl`09ttiosb+2, chars_left`09`09; # chars read X`09movab`09ttbuf, char_pointer`09`09; store address of character X50$: X`09decl`09chars_left X`09movzbl`09@char_pointer, r0`09`09; get next char X`09incl`09char_pointer`09`09`09; point to next X`09subb2`09#`5EA/0/, r0`09`09`09; convert from ascii to binary X`09blss`09200$`09`09`09`09; invalid command X`09cmpb`09r0, #9 X`09bgeq`09150$`09`09`09`09; invalid command (maybe quit) X`09bbc`09r0, valid_move, 200$`09`09; invalid command X.if df $$tank X`09tstl`09chars_left`09`09`09; any chars left ? X`09bleq`09100$`09`09`09`09; no --> 100$ X`09cmpb`09@char_pointer, #`5EA/5/`09`09; is next command fire ? X`09bneq`09100$`09`09`09`09; no --> 100$ X`09incl`09char_pointer X`09decl`09chars_left X`09bisb2`09#`5EB10000, r0`09`09`09; add 16 to indicate fire X.endc X100$: X`09rsb X150$: X`09cmpb`09r0, #`5EA/e/-`5EA/0/`09`09; was an "e" typed ? X`09beql`09180$ X`09cmpb`09r0, #`5EA/E/-`5EA/0/`09`09; was an "E" type ? X`09bneq`09200$ X180$: X`09clrl`09r0`09`09`09`09; quit is move = 0 X`09rsb X200$: X`09mnegl`09#1, r0`09`09`09`09; no move given X`09rsb X X`09.entry`09- XMBXREAD,`09`5Em<> X;+ X; This is an AST routine which executes when the mailbox record has been rea Vd. X; The record itself is a status message which is assumed to say that X; unsolicited data is available at the terminal X;- X`09blbc`09mbxiosb, 100$`09`09; on error, dont re-que read X;`09we could have SS$_CANCEL or SS$_ABORT from the $CANCEL in the X;`09exit handler X`09movb`09#1, data_ready`09`09; indicate data is there X`09bsbw`09queue_mbxread`09`09; queue another read request X100$: X`09ret X XQUEUE_MBXREAD: X`09$qio_s`09efn=#2, func=#io$_readvblk, chan=mbxchan, iosb=mbxiosb,- X`09`09astadr=mbxread,- X`09`09p1=mbxbuf, p2=#mbxbuf_siz X`09blbc`09r0, 100$ X`09rsb X100$: X`09bsbw`09error X`09rsb X XTTWRITE:: X;+ X;`09bsbw`09ttwrite X;`09r3 contains length of buffer to write X;`09the buffer is outbuf X;- +-+-+-+-+-+-+-+- END OF PART 1 +-+-+-+-+-+-+-+- -+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+ X`09movl`09r3, outbuf_qio+qio$_p2`09`09; store length of buffer X`09$qiow_g`09outbuf_qio X`09blbc`09r0, 100$ X`09rsb X100$: X`09bsbw`09error X`09rsb X X X`09.entry`09- Xsnake_screen, `5Em X;+ X;`09CALL SNAKE_SCREEN( array, length ) X;`09BYTE ARRAY( LENGTH ) X;`09copies string to update screen into shared memory X;- X`09movl`09@8(ap), r0`09`09; get length X`09movl`09r0, screen_len`09`09; store length X`09movc3`09r0, @4(ap), screen_buf`09; copy text X`09ret X X`09.entry`09- Xsnake_write, `5Em<> X;+ X;`09CALL SNAKE_WRITE( array, length ) X;`09BYTE ARRAY( LENGTH ) X;`09writes buffer to terminal in noformat mode X;- X`09movl`094(ap), output_qio+qio$_p1`09; store address of buffer X`09movl`09@8(ap), output_qio+qio$_p2`09; store length of buffer X`09$qiow_g`09output_qio X`09blbc`09r0, 100$ X`09ret X100$: X`09bsbw`09error X`09ret X X`09.entry`09- Xsnake_dead, `5Em<> X;+ X;`09CALL SNAKE_DEAD( player # ) X;- X`09subl3`09#1, @4(ap), r0`09`09`09; get # of snake who died X`09bbss`09r0, you_just_died, 100$`09`09; set flag saying he died X100$:`09ret X X X`09.entry - XCANCELTYPEAHEAD, `5Em<> X`09clrl`09r0 X`09tstw`09ttchan`09`09; check channel is open X`09beql`09100$ X`09$qiow_s`09func=#io$_readvblk!io$m_purge!io$m_timed,- X`09`09chan=ttchan, p1=ttbuf`09; do read with 0 length buffer (p2) X100$:`09ret`09`09`09; return with status in r0 X XERROR: X`09blbs`09r0, 100$ X`09pushl`09r0 X`09calls`09#1, G`5Elib$signal X100$: X`09rsb X X`09.entry`09- Xcontrol_c, `5Em<> X`09movb`09#1, control_c_flag X`09ret X X X`09.page X`09.entry`09- XSNAKE_INIT, `5Em`09`09`09`09; snake game X;+ X;`09I = SNAKE_INIT( player # , game ) X;`09returns I = 1 if you are master snake. X;`09returns your player # as a integer X;`09returns game = 1 if there is a game in progress X;- X X`09calls`09#0, G`5Ettinit`09`09`09; open terminal X; X`09$ascefc_s efn=#64, name=snake_desc_2`09; associate event flag cluster X`09bsbw`09error X; X;`09$open`09fab=snake_fab`09`09`09; open section file X;`09bsbw`09error X X`09$deltva_s inadr=map_range`09`09; delete memory were global X`09bsbw`09error`09`09`09`09; memory will be mapped X X`09$crmpsc_s inadr=map_range, flags=#sec$m_gbl!sec$m_wrt!sec$m_pagfil, - X`09`09gsdnam=snake_map_name, -`09; chan=snake_fab+fab$l_stv,- X`09`09pagcnt=#4 X`09bsbw`09error X X`09cmpl`09r0, #ss$_created`09`09; are we first to map section X`09bneq`0950$`09`09`09`09; no X`09movab`09share_data+4, r3 X`09movc5`09#0, (r3), #0, #512-4, (r3)`09; clear everything except count X`09$clref_s efn=#flag$v_game+64`09`09; say not game X`09movl`09#39814571, seed`09`09`09; init random n.g. seed X`09movl`09#snake, r0`09`09`09; 8 snakes X20$: X`09movl`09r0, start_position-4`5Br0`5D`09; init start position X`09sobgtr`09r0, 20$ X50$: X`09blbc`09abort, 60$`09`09`09; if not abort --> 60$ X`09callg`09text_abort, snake_write X`09$exit_s #1 X60$: X`09bsbw`09queue_mbxread`09`09`09; start terminal read X; X`09bbss`09#0, master_flag, 100$`09`09; see if a master snake exists X`09`09`09; this should be interlocked on a multi-processor X;+ X; We will have to be the master snake X;- X`09movb`09#1, master`09`09`09; indicate we are master snake X`09$setef_s efn=#7`09`09`09`09; set for first call X100$: X; X`09clrl`09r1`09`09`09`09; start at player 0 (bit0=1) X150$: X`09bbcs`09r1, players, 200$`09`09; see if this snake is free X`09incl`09r1`09`09`09`09; go to next snake X`09cmpl`09r1, #snake`09`09`09; have we checked all snakes? X`09blss`09150$`09`09`09`09; no --> 150$ X`09mnegl`09#1, r1`09`09`09`09; player = -1 means none X200$: X`09movl`09r1, player`09`09`09; store my snake number (0-7) X`09movl`09player, @4(ap)`09`09`09; and return it X500$: X`09movzbl`09game_going, @8(ap)`09`09; return game going flag X X`09movl`09r1, r3 X`09$getjpi_s itmlst=username_jpi`09`09; get our username X`09mull2`09#name_size, r3`09`09`09; get offset to start of name X`09blss`09600$`09`09`09`09; no snakes available X`09movc5`09username_siz, username_buf, #`5Ea/ /, #name_size, name(r3) X`09`09`09`09`09`09; copy username X600$: X`09$dclexh_s desblk=exit_block`09`09; declare exit handler X`09bsbw`09error X X`09movzbl`09master, r0`09`09`09; return master snake status X`09ret X Xmaster_wait: X;+ X; master snake has to wait some time for other snakes to start playing X; called from SNAKE_START X;- X`09incl`09game_count`09`09`09; say another game being played X220$:`09clrb`09player_bits`09`09`09; no other players X`09bbss`09player, player_bits, 400$`09; say I am playing X400$: X`09$clref_s efn=#flag$v_synch+64 X;+ X;`09randomise starting positions X;- X`09moval`09start_position, r4`09`09; starting position numbers X`09movl`09#1, r2`09`09`09`09; snake index (start at 1) X500$: X`09pushal`09seed`09`09`09`09; random number seed X`09calls`09#1, G`5Emth$random`09`09; random real in r0 X`09addl3`09#1, r2, r3`09`09`09; snake + 1 X`09cvtlf`09r3, r3`09`09`09`09; as real X`09mulf2`09r3, r0`09`09`09`09; get snake to change pos with X`09cvtfl`09r0, r0 X`09movl`09(r4)`5Br0`5D, r1`09`09`09; swap these positions X`09movl`09(r4)`5Br2`5D, (r4)`5Br0`5D X`09movl`09r1, (r4)`5Br2`5D X`09aobleq`09#7, r2, 500$ X; X;`09moval`09start_position, r4 X`09movab`09move, r3 X`09movl`09#snake, r2`09`09`09; number of snakes X600$: X`09movl`09(r4)+, r0`09`09`09; get start position (1-8) X`09movb`09start_direction-1`5Br0`5D, (r3)+`09; copy start direction X`09sobgtr`09r2, 600$ X; X`09$setimr_s efn=#flag$v_game+64,-`20 X`09`09`09daytim=second_1`09`09; wait a time for other snakes X`09$waitfr_s efn=#flag$v_game+64`09`09; say that a game is going X`09movb`09#1, game_going`09`09`09; say game going X`09$clref_s efn=#flag$v_endofgame+64`09; say not end of game X`09$setef_s efn=#7`09`09`09`09; sets event flag for first X`09`09`09`09`09`09; call to snake_wait X`09$setimr_s efn=#flag$v_synch+64,-`09`09 X`09`09`09 daytim=start_wait X`09$waitfr_s efn=#flag$v_synch+64 X`09; this allows other snakes to set bit saying they are playing X X`09rsb X X`09.entry`09- XSNAKE_START, `5Em X;+ X;`09CALL SNAKE_START( PLAYERS , START_POSITION ) X;`09INTEGER PLAYERS, START_POSITION(8) X;`09waits 5? seconds for other players to run game X;`09The master snake is assumed to have waited some additional time X;`09Returns PLAYERS, bit I <> 0 if that player is active X;`09START_POSITION(I) is the starting location of snake I, (1-8) X;- X`09blbc`09master, 500$`09`09`09; are we master snake ? X`09bsbw`09master_wait X`09brb`09800$ X200$: X`09$exit_s #1`09`09`09`09; game aborted so stop X500$: X`09$waitfr_s efn=#flag$v_game+64`09`09; wait until a game starts X`09blbs`09abort, 200$`09`09`09; if game stopped --> 200$ X`09bbss`09player, player_bits, 600$`09; say I am playing X600$:`09$waitfr_s efn=#flag$v_synch+64`09`09; synchronise X`09blbs`09abort, 200$`09`09`09; if game stopped --> 200$ X800$: X`09movzbl`09player_bits, r4`09`09`09; get player bits X`09ashl`09#flag$v_done, r4, other_players ; used by master snake X`09movl`09r4, @4(ap)`09`09`09; store player bits X`09clrl`09chars_left`09`09`09; cancel type ahead X`09clrb`09data_ready`09`09`09; make us do a read X`09$qiow_g read_qio`09`09`09; clear out type-ahead X;`09return starting positions X`09moval`09start_position, r0`09`09; address of new positions X`09movl`098(ap), r2`09`09`09; address of where to put them X`09movl`09#snake, r1`09`09`09; number of snakes X900$: X`09movl`09(r0)+, (r2)+ X`09sobgtr`09r1, 900$ X X`09mnegl`09#1, last_move_count`09`09; invalidate last counter X X`09ret X X XSNAKE_WAIT:: X;+ X;`09BSBW SNAKE_WAIT X; `09wait until we are told to read players command(s) X;- X`09blbs`09master, 200$`09`09`09; are we master snake ? X`09$waitfr_s efn=#flag$v_read+64`09`09; if not then wait for flag X`09rsb X200$:`09; master snake waits and then sets flag for all players X`09$cantim_s reqidt=#check_timer`09`09; cancel checking timer X`09$waitfr_s efn=#7`09`09`09; wait for previous timer X`09$setimr_s efn=#8, daytim=check_wait, - X`09`09astadr=check_ast, reqidt=#check_timer ; set off checking timer X`09$setimr_s efn=#7, daytim=update_wait X`09$clref_s efn=#flag$v_update+64`09`09; clear next flag to wait on X`09movl`09#flag$v_done+64, r2`09`09; clear each players done flag X`09$clref_s efn=r2`09`09`09`09; player 0 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2`09`09`09`09; player 7 X; X`09$clref_s efn=#flag$v_synch+64 X`09$setef_s efn=#flag$v_read+64`09`09; tell everybody to do read X`09rsb X X XSNAKE_READ:: X;+ X;`09BSBW SNAKE_READ X;`09read all users moves and store them into the byte array MOVES(*) X;- X`09bsbw`09ttread`09`09`09`09; read users commands, if any X`09tstb`09r0`09`09`09`09; anything read ? X`09blss`09800$`09`09`09`09; no X500$: X`09movl`09player, r1`09`09`09; get our player number X`09movb`09r0, move(r1)`09`09`09; store our move X`09bneq`09800$`09`09`09`09; if not quit --> 800$ X`09clrl`09score`5Br1`5D`09`09`09; clear score X`09clrl`09n_games`5Br1`5D X`09clrl`09wins`5Br1`5D X`09$exit_s #1`09`09`09`09; and exit program X800$: X`09addl3`09#flag$v_done+64, player, r1 X`09$setef_s efn=r1`09`09`09`09; say that read is complete X900$: X`09blbc`09master, 1000$ X`09$wfland_s efn=#64, mask=other_players`09; wait for all players to read X`09incl`09move_count`09`09`09; onto next move X`09$clref_s efn=#flag$v_read+64`09`09; clear next flag to wait on X`09$setef_s efn=#flag$v_update+64`09`09; tell everybody to update X`09brb`091050$ X1000$: X`09$waitfr_s efn=#flag$v_update+64`09`09; wait for all reads to complete X`09blbs`09master_flag, 1050$`09`09; check for master snake OK X`09movl`09player, r1`09`09`09; get our player number X`09clrb`09move(r1)`09`09`09; store our move ( quit ) X1050$: X`09rsb X X X`09.entry`09- XSNAKE_PLAY, `5Em X;+ X;`09called once at the start of the game. X;`09I then call the Pascal routine ADD_HEAD to perform the moves. X;- X`09blbs`09master, 1000$`09`09; master snake does all the work X100$: X`09bsbw`09snake_wait X`09bsbw`09snake_read X`09$waitfr_s efn=#flag$v_synch+64`09; wait until screen update there X`09bsbw`09snake_update`09`09; update screen X`09brb`09100$ X X900$: X`09clrb`09game_going`09`09; tell other snakes games finished X`09$setef_s efn=#flag$v_synch+64`09; wake other snakes up X`09bsbb`09snake_update`09`09; write out last move X`09ret X X1000$:`09; master snake moves every snake X`09bsbw`09snake_wait X`09bsbw`09snake_read X`09callg`09add_head_par, G`5Eadd_head`09; call Pascal routine X`09`09`09`09`09`09; returns 1 if game still going X`09blbc`09r0, 900$`09`09; game has ended --> 900$ X`09$setef_s efn=#flag$v_synch+64`09; wake other snakes up X`09bsbb`09snake_update`09`09; update our screen X`09brb`091000$ X X X`09.enable local_block X500$: X`09$exit_s #1`09`09`09; game aborted, so exit image X Xsnake_update:: X`09blbs`09abort, 500$ X`09blbs`09dead, 80$`09`09; if we are dead, then no head X;`09replace your snake head with a diamond symbol X`09movc3`09screen_len, screen_buf, outbuf`09; copy update string X`09movl`09player, r2`09`09; get my snake number X`09addw2`09#`5EA/1/+`5EX80, r2`09`09; get number with parity bit set X`09locc`09r2, screen_len, outbuf X`09beql`0950$`09`09`09; could not find it !!! X`09movb`09#`5EA/`60/, (r1)`09`09; change to diamond X50$: X`09callg`09update_par, snake_write X`09blbc`09game_going, 100$`09; bit clear if game has finished X`09bbsc`09player, you_just_died, 60$ ; see if we just died X`09rsb X60$:`09movb`09#1, dead`09`09; say we are dead X`09callg`09text_wait, snake_write`09; tell them to wait for next game_exit, X`09rsb X80$:`09; dont copy buffer if no head to update because we are dead X`09callg`09update_par2, snake_write X`09blbc`09game_going, 100$ X`09rsb X100$: X`09$setimr_s efn=#6, daytim=second_1`09; so we can see last move X`09$waitfr_s efn=#6 X`09ret`09`09`09`09; return from SNAKE_PLAY if end game X`09.disable local_block X X X`09.entry`09- XCHECK_AST, `5Em X;+ X;`09called when check_timer expires (2 seconds) X;`09we should only get here if one of the other snakes has aborted X;`09or `5ES ed . Force the snake out of the game. X;- X`09$readef_s efn=#64, state=cluster_2`09; get done flags X`09extzv`09#flag$v_done, #snake, cluster_2, r2 ; get done flags X;`09movb`09other_players+1, r3`09`09; get other players X`09bicw3`09r2, other_players+1, r3`09`09; find players who have not X`09`09`09`09`09`09; responded X`09bicw2`09r3, other_players+1`09`09; and say they are dead X`09clrl`09r2`09`09`09`09; snake 0 X100$:`09bbc`09r2, r3, 200$ X`09clrb`09move(r2)`09`09`09; say snake has quitted X`09addl3`09#flag$v_done+64, r2, r0`09`09; get event flag X`09$setef_s efn=r0`09`09`09`09; set event flag so I will X`09`09`09`09`09`09; wake up on return from here X200$:`09aoblss`09#snake, r2, 100$`09`09; for all 8 snakes X X`09ret X X X`09.entry`09- XSNAKE_GAME_END, `5Em<> X;+ X;`09synchronizes the end of the game X;- X`09clrb`09dead`09`09`09; we are not dead X`09blbc`09master, 500$`09`09; if not master snake --> 500$ X`09$clref_s efn=#flag$v_game+64`09; say game not in progress X`09clrb`09game_going`09`09; and again X`09$setimr_s efn=#flag$v_endofgame+64, daytim=second_2 X`09clrw`09you_just_died`09`09; reset died flags X500$: X`09$waitfr_s efn=#flag$v_endofgame+64 ; wait for end of game X`09blbs`09abort, 800$`09`09; if we should abort --> 800$ X`09ret X800$:`09; we must abort. Probably because master snake stopped X`09$exit_s #1 X X X`09.entry`09- XSNAKE_EXIT, `5Em X;+ X;`09called as an exit handler X;- X`09$cancel_s chan=mbxchan`09`09; cancel mailbox read X X`09movl`09player, r3`09`09; get my snake number X`09blss`0980$`09`09`09; we never were playing X`09clrb`09move(r3)`09`09; make next move a quit X`09addl3`09#flag$v_done, r3, r2`09; get done bit X`09bbcc`09r2, other_players, 50$`09; stop master snake from waiting for me X50$:`09addl2`09#64, r2`09`09`09; make into event flag X`09$setef_s efn=r2`09`09`09; say input done X`09bbcc`09r3, players, 60$`09; say this snake available X60$: X`09clrl`09score`5Br3`5D`09`09; zero score X`09clrl`09n_games`5Br3`5D`09`09; zero # of games played X80$: X`09blbc`09master, 100$`09`09; are we master snake ? X`09movb`09#1, abort`09`09; tell all other snakes to abort +-+-+-+-+-+-+-+- END OF PART 2 +-+-+-+-+-+-+-+- -+-+-+-+-+-+-+-+ START OF PART 3 -+-+-+-+-+-+-+-+ X`09clrb`09master_flag`09`09; say no master snake X`09$setef_s efn=#flag$v_read+64`09; wake everybody up X`09$setef_s efn=#flag$v_update+64 X`09$setef_s efn=#flag$v_endofgame+64 X`09$setef_s efn=#flag$v_synch+64 X`09$setef_s efn=#flag$v_game+64`09; for people waiting for a game X100$: X;`09clear screen and put out of graphics mode X`09callg`09text_end_game, snake_write X`09blbc`09abort, 200$`09`09; game is not being aborted --> 200$ X`09callg`09text_abort, snake_write X200$: X`09$deltva_s inadr=ret_range`09; delete global section X X;`09$dassgn_s chan=snake_fab+fab$l_stv ; deassign channel X X`09ret X X`09 X`09.entry`09- XNAME_SET, `5Em X;+ X;`09CALL NAME_SET( name ) X;`09set this players name X;- X`09mull3`09#name_size, player, r3`09; get our player number (0-7) X`09addl2`09#13, r3`09`09`09; skip username X`09movc3`09#name_size-13, @4(ap), name(r3) ; store name in shared memory X`09ret X X`09.entry`09- XNAME_GET, `5Em X;+ X;`09CALL NAME_GET( name , player # ) X;`09returns the name of specified player (1-8) X;- X`09subl3`09#1, @8(ap), r1`09`09; get player number (0-7) X`09mull2`09#name_size, r1`09`09; offset to this players name X`09movc3`09#name_size, name(r1), @4(ap) ; return players name X`09ret X X`09.entry`09- XSCORE_SET, `5Em<> X;+ X;`09CALL SCORE_SET( player #, score , # games , # wins ) X;- Xplayer_arg = 4 Xscore_arg = 8 Xgames_arg = 12 Xwins_arg = 16 X`09subl3`09#1, @player_arg(ap), r1`09`09; get our player # (0-snake) X`09movl`09@score_arg(ap), score`5Br1`5D`09; store score X`09movl`09@games_arg(ap), n_games`5Br1`5D X`09movl`09@wins_arg(ap), wins`5Br1`5D X`09ret X X`09.entry`09- XSCORE_GET, `5Em<> X;+ X;`09CALL SCORE_GET( player , score , # games , # wins ) X;- X;player_arg = 4 X;score_arg = 8 X;games_arg = 12 X;wins_arg = 16 X`09subl3`09#1, @player_arg(ap), r1`09`09; get player # (0-snake) X`09movl`09score`5Br1`5D, @score_arg(ap)`09; return score X`09movl`09n_games`5Br1`5D, @games_arg(ap)`09; return # of games played X`09movl`09wins`5Br1`5D, @wins_arg(ap)`09`09; return # of wins X`09ret X X`09.entry`09- Xsnake_game_count, `5Em<> X;+ X;`09CALL SNAKE_GAME_COUNT( # games ) X;`09returns # of games played (total) X;- X`09movl`09game_count, @4(ap) X`09ret X X`09.end $ CALL UNPACK SNAKE.MAR;1 235814742 $ create 'f' X`1B`5BH`1B`5BJ`1B(B`1B`5B0m X`1B`5B1;1H`1B(0lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk lqqqqqqqqqqqqq O`1B V(Bbject `1B(0qqqqqqqqqqqqqk X`1B`5B2;1Hx`1B`5B2;39Hx x`1B`5B2;78Hx`1B`5B3;1Hx lqq lk x lqk k x V lqq x x T`1B(Bo Be The La X`1B`5B3;59Hst Snake Alive `1B(0x`1B`5B4;1Hx x xmk x x mk x lj x V x x`1B`5B4;78Hx X`1B`5B5;1Hx mqqqkx mkx xqqu twj tq x mqqqqqqqqqqqqqqqqqqqqqqq Vqqqqqqqqqqqj X`1B`5B6;1Hx xx xx x x xmk x x lqqqqqqqqqqqqq H`1B(Baza Vrds `1B(0qqqqqqqqqqqqk X`1B`5B7;1Hx lqqqjx mj m x x mk mqqqk x x`1B`5B7;78Hx`1B`5B8;1Hx V x x x x `20 X`1B`5B8;33Hx x x H`1B(Bitting Any Object Will Kill You `1B(0x`1B`5B9;1 VHx`1B`5B9;39Hx x`1B`5B9;78Hx X`1B`5B10;1Hmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj mqqqqqqqqqqqqqqqqqqqqqq Vqqqqqqqqqqqqj X`1B`5B11;1Hlqqqqqqqqqqq I`1B(Bntroduction `1B(0qqqqqqqqqqqqk lqqqqqqqqqqqq V C`1B(Bontrols `1B(0qqqqqqqqqqqqk X`1B`5B12;1Hx`1B`5B12;39Hx x`1B`5B12;78Hx`1B`5B13;1Hx M`1B(Bulti User Game V For Up To 8 Players `1B(0x x`1B`5B13;58H8 `1B(B- X`1B`5B13;61H Up`1B`5B13;78H`1B(0x`1B`5B14;1Hx`1B`5B14;39Hx x`1B`5B14;78Hx` V1B`5B15;1Hmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq X`1B`5B15;39Hj x 4 `1B(B- Left`1B`5B15;66H6 - Right `1B(0x`1B`5B16;1Hl Vqqqqqqqqqqqqq S`1B(Bymbols `1B(0qqqqqqqqqqq X`1B`5B16;35Hqqqqk x`1B`5B16;78Hx`1B`5B17;1Hx`1B`5B17;39Hx x`1B`5B17;58H2 V `1B(B- Down`1B`5B17;78H`1B(0x`1B`5B18;1Hx Y`1B(Bou -`20 X`1B`5B18;11H`1B(0`60 O`1B(Bthers - 1..8 `1B(0x x`1B`5B18;78Hx` V1B`5B19;1Hx`1B`5B19;39Hx x T`1B(Bype "E"`20 X`1B`5B19;60Hto Exit Game `1B(0x`1B`5B20;1Hmqqqqqqqqqqqqqqqqqqqqqqqqqqqq Vqqqqqqqqqj mqqqqqqqqqqqqqqqqqqq X`1B`5B20;63Hqqqqqqqqqqqqqqqj`1B`5B21;1Hlqqqqqqqqqqqq M`1B(Bessages `1B(0qqqq Vqqqqqqqqqqqk lqqqqqqqqqqqqq N`1B(Ba X`1B`5B21;60Hme `1B(0qqqqqqqqqqqqqqqk`1B`5B22;1Hx`1B`5B22;39Hx x `1B(B* V`1B(0`7E `1B`5B22;70H`7E* x X`1B`5B23;1Hmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj mqqqqqqqqqqqqqqqqqqqqqq Vqqqqqqqqqqqqj`1B`5B1;1H X`1B* $ CALL UNPACK SNAKE.SCN;1 185950272 $ create 'f' X`09SUBROUTINE`09HELP_SCREEN XC X`09PARAMETER ESC = 27 X`09CHARACTER Line*256 X BYte REP X`09INTEGER Len_Line,ErrNum XC X`09CALL image_dir() XC X Write(5,111)esc X111 Format(X,A1,'<') X1`09OPEN(UNIT=4,FILE='IMAGE_DIR:SNAKE.SCN',ReadOnly, X`091 STATUS='OLD',IoStat=ErrNum) X If (ERRNUM.EQ.30) Goto 50 X If (ERRNUM.NE.0 ) Goto 999 X100 READ(4,110,END=200) LEN_LINE, LINE(:LEN_LINE) X110 FORMAT(Q,A) X WRITE(5,120) LINE(:LEN_LINE) X120 FORMAT(1X,A) X GOTO 100 X200`09close (unit = 4) X999`09RETURN XC X50`09Write(5,51),Esc,Esc X51 FORMAT(X,A1,'`5B2J',A1,'`5B1;1HPlease wait...') X Call Sleep(4) X Goto 1 XC X END $ CALL UNPACK SNAKEH.FOR;1 1311099332 $ create 'f' X X`7B$S-`7D X`7B$C+`7D X`7B X X XXXXX X X XXXXX X X XXXXXX X X X XX X X X X X X `20 X X X X X X X X X X `20 X XXXXX X X X XXXXXXX XXXX XXXXX`20 X X X X X X X X X X `20 X X X X XX X X X X X `20 X XXXXX X X X X X X XXXXXX X `20 X X`09`09Program`09: Snake X X`09`09Authors`09: Rex Croft - Macro X X Murray Speight - Pascal`20 X X`09`09Place`09: University Of Waikato`20 X X`09`09Date `09: May 1982`20 X X`09Software Is Subject To Change Without Notification X The Author And His Family assume No Rsponsability For X`09Its Reliabliity Or Use.`20 X X `7D X XProgram Snake(Input,Output); X XLabel`099999; `7B For Abortive exit Of Pgm `7D X X XConst `09Max_Num_Players`09= 8; `7B Up To 8 Players `7D X`09Screen_Dim_X `09= 23; `7B PLaying Board 40 * 23 `7D X`09Screen_Dim_Y`09= 40; X`09Len_Of_Buff`09= 1024; `7B Buffer to Write Chars `7D X Max_Name_Length = 32; `7B Lenngth of a players name `7D X XType `09Player_Responce = Packed Array `5B1..Max_Num_Players`5D Of Char; X`09Buffer`09`09= Packed Array `5B1..Len_Of_Buff`5D Of Char;`09 X`09Positions`09= Array `5B1..Max_Num_Players`5D Of INteger; X`09Players_Screen`09= Array `5B1..Screen_Dim_X,1..Screen_Dim_Y`5D Of Char; X`09Died_Type`09= Array `5B1..Max_NUm_Players`5D Of Boolean; X`09Name_Line`09= Packed array `5B1..max_Name_Length`5D of Char; X Name_Table`09= Array `5B1..Max_Num_Players`5D of name_LIne; X XVar `09Responce `09,`09`09`09`7B What Players Have Typed `7D X`09Head_Sym`09: Player_Responce; `7B What Symbol is THe Head `7D X`09Screen`09`09: Players_Screen; `7B 23 * 40 Array For Screen`7D X`09Name`09`09: Name_Table; `7B Names Of Each Player `7D X Init_Pos_X`09, `7B Where initaially Players St Vart `7D X Init_pos_Y , `7B "" "" For Y Coord `7D X`09Score`09`09, `7B Score Of Each PLayer `7D X Game`09`09, `7B Num Games Each PLayer Played ` V7D X`09Games_Won `09, `7B Games Won By Each PLayer `7D X`09Move_X`09`09, `7B What Dir Each Playe Is Moving X C Voord `7D X`09Move_Y`09`09, `7B "" "" Y Coord `7D X`09Head_X`09`09, `7B Where The Head Is For Each Player V X Coord `7D X`09Head_Y`09 `09, `7B "" "" Y Coord `7D X`09Tail_X`09`09, `7B Where The Tail Is For Each Player V X Coord `7D X`09Tail_Y`09`09: Positions; `7B "" "" Y Cord `7D X`09TT_Buff`09`09: Buffer; `7B Lenght Of Buffer To Hold Screen V Output `7D X`09TT_Len`09`09, `7B String To Hold Screen Output `7D X Who_Is_PLaying , `7B Word With Bits Set As To V Who is Playing `7D X`09You`09`09, `7B Which Number You are `7D`20 X`09Dummy `09`09, `7B Dummy argument `7D X`09Num_players , `7B How Many people are Playing ` V7D X`09Max_Player_Number , `7B The Highest PLayers Number wh Vo is Playing `7D X Num_Moved_Last_Round , `7B Number of players who mo Vved last Round ( Last Screen Update ) `7D X`09Players_Removing`09: Integer; `7B Are We Removing Odd 1 or even 2 pl Vayers Tails `7D X`09Quit`09`09, `7B Has The PLayer Quit (not playing ) V or is He Playing `7D X`09Died `09`09: Died_Type; `7B Has The PLayer Died ( Died If He h Vas Quit ) `7D X`09Esc`09`09: Char; `7B esc For escape sequences `7D X`09Seed`09`09: Real; `7B Seed for random number generaotor ` V7D X X XProcedure Break_Buff; X X Procedure Snake_Screen( Var Line : Buffer ; Var Lenght : Integer );extern V;`20 X X`7B Only Call This Once From The Add_head Function`20 X X Does not write array to screen `7D X XBegin X Snake_Screen(TT_Buff,TT_Len);`20 X TT_Len := 0; Xend; X X XProcedure Help_Screen;extern; X XProcedure Pos( X,Y : Integer ; Ch : Char ); X X`7B Write Char at Pos X,Y in Buffer `7D X XBegin X TT_Buff`5BTT_Len+1`5D := Esc; X TT_Buff`5BTT_Len+2`5D := 'Y'; X TT_Buff`5BTT_Len+3`5D := Chr(31+X); X TT_Buff`5BTT_Len+4`5D := Chr(31+Y); X TT_Buff`5BTT_Len+5`5D := Ch; X TT_Len := TT_Len + 5; Xend; X XFunction at(X,Y: Integer):Char; X X`7B Posotion Cursor at X , Y this Is For Use In Write Statments `7D X XBegin X Write(esc,'Y',chr(31+X),Chr(31+Y)); X at := Chr(0); Xend; X X XFunction Snake_Init(Var You : INteger ; Var Game_going : Integer):Integer;e Vxtern; X XProcedure Name_Set(Var Name : Name_Line );extern; X XProcedure Name_Get( VAR Name : Name_Line ; Play : Integer );extern; X XProcedure Score_Set( Player : INTEGER; VAR Score,Games_PLayed,wins : INteger V); X`09`09`09`09`09`09`09extern; XProcedure Score_Get( Player : INTEGER; VAR Score,Games_Played,wins : Integer V ); X`09`09`09`09`09`09`09extern; XProcedure Snake_Start( Var Whos_PLaying : Integer ; var Rand : Positions );E Vxtern; X XProcedure Snake_Read(Var Directions : Player_Responce );Extern; X XProcedure Snake_Game_End;extern; X XProcedure Snake_Wait;Extern; X XProcedure Snake_Game_count( Var Num : Integer);extern; X XProcedure Snake_Dead(Var PLayer : Integer );extern; X XProcedure Sleep( Num_Sec : Integer);extern; X XProcedure Draw_Scores; X XVar I,num_on_table,play,max_score,Top_play,Total_Num_Games,This_score: Integ Ver; X X XBegin X Num_on_Table := 0; X Writeln(esc,'H',Esc,'J',Esc,'G',esc,'<'); X Writeln(' Player User Name Score Game Won Gra Vph'); X writeln(' ------ ---- ---- ----- ---- --- --- V--'); X writeln; X Max_score := -99999; X X `7B Find The Top Player goes By The his Score And Num Of Games Played `7 VD X For PLay := 1 to Max_Num_PLayers do begin X Score_get(Play,Score`5BPLay`5D,Game`5BPLay`5D,Games_won`5Bplay`5D); X If Game`5BPlay`5D > 0 Then Begin X This_score := Round(Score`5Bplay`5D / (Game`5Bplay`5D)**(0.8)); X If This_score > Max_score Then Begin X Top_Play := Play; X Max_score := This_score + 1; X end; X end; X end; X For Play := 1 to Max_Num_PLayers do Begin X If Game`5BPLay`5D > 0 Then Begin `7B IF Games PLayed > 0 Then You A Vre PLaying `7D X Num_On_Table := Num_On_Table + 1; X If PLay = Top_PLay Then`20 X Write(esc,'`5B1m'); `7B High intensity Flash `7D X Write(Play:4); X Write(' ',Name`5BPlay`5D:32); X write(Score`5BPLay`5D:7); `7B Print Info `7D X Write(Game`5BPlay`5D:6); X Write(Games_won`5Bplay`5D:5); X Write(' ',Esc,'`5B7m'); `7B Rev Video `7D X If PLay = Top_PLay Then `20 X Write(' *** Champ *** ') X `09 Else X For I := 1 to Round(Score`5Bplay`5D*15 / ((Game`5Bplay`5D)**(0.8 V)*max_score)) do`20 X Write(' '); X Writeln(esc,'`5B0m'); `7B Normal Video `7D X end; X End; X writeln; X X`7B Print The Games You Have Played With The Totak Num of Games Played so Fa Vr `7D X Snake_Game_Count( Total_Num_games ); X Writeln(' Game # ',Game`5BYou`5D:1,'`09Total # ',Total_Num_Games:1); X writeln; X writeln; X If Num_on_Table <= 1 Then`20 X Goto 9999; X writeln(' Please Wait For Next Game ..... '); X writeln(esc,'`5B?2l',esc,'F'); Xend; X XProcedure Draw_screen; X XVar play,I,X,Y,Line_at : Integer; X X Function Min(A,B:Integer):Integer; X X Begin X If A < B Then`20 X Min := A`20 X Else X Min := B X end; X XBegin `7B Draw Screen `7D X Write(at(1,1),esc,'J',esc,'<',esc,'(0',esc,'<',esc,'(0'); `7B Clear H Vome `7D X Write(esc,'#6l'); X For Y := 1 To (Screen_Dim_Y-2) Do`20 X Write('q'); X Writeln('k'); X For X := 2 To ( Screen_dim_X - 1 ) Do begin X Write(esc,'#6x'); X For Y := 1 to (Screen_Dim_Y-1) do`20 X Write('`7E'); X Writeln('x'); X end; X write(esc,'#6m'); X For Y := 1 to (Screen_Dim_Y-1) Do`20 X Write('q'); X Writeln('j'); X X`7B Show Who You Are At Thje Bottom Of The Screen `7D X Writeln(`7BEsc,'`5B24;1H',Esc,'#6',Esc,'(BYou # ',You:1,`7D X`09 esc,'`5B?2l',esc,'F',at(1,1)); `20 Xend; X X `20 XProcedure initalise_Positions; X X X XVar Mult,Play,X,Y : Integer; X X Rand`09 : Positions; X XBegin X XPlayers_Removing := -1; `7B On First Few Moves Don't remove Tail `7D X XSnake_Start(Who_Is_Playing,Rand); X X X`7B Randomly Position The Starting Pos Of The PLayers `7D XFor play := 1 to Max_num_players do Begin X Head_X`5BPlay`5D := Init_Pos_X`5BRand`5BPlay`5D`5D; X Head_Y`5Bplay`5D := Init_Pos_Y`5BRand`5BPLay`5D`5D; X Move_X`5Bplay`5D := 1; X MOve_Y`5BPlay`5D := 0; Xend; XTail_X := Head_X; XTail_Y := Head_Y; X +-+-+-+-+-+-+-+- END OF PART 3 +-+-+-+-+-+-+-+- -+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+ XMult := 2**7; `7B 2 ** Number of PLayers - 1`7D XNum_Players := 0; X X`7B Examine Each Bit In Mult To See If You Are Playing `7D XMax_player_number := 0; XFor Play := Max_Num_PLayers downto 1 do begin X If ( Who_Is_PLaying div Mult ) = 1 Then begin X Name_Get(Name`5BPlay`5D,Play); X Num_Players := Num_PLayers + 1; X Quit`5Bplay`5D := False; `7B Bit Set You Are Playing `7D X Who_is_Playing := Who_is_Playing - Mult; X If Max_player_number = 0 Then`20 X Max_player_number := play ;`7B The Highest Numbered Player `7D X end else begin X Quit`5BPlay`5D := True; `7B Bit Not Set Not Playing ie Quit `7D X end; X Mult := Mult div 2; Xend; X XNum_Moved_Last_Round := 0; X X`7B If You are PLaying Then You Havnt Died `7D XFor Play := 1 to Max_Num_Players Do Begin X If Not Quit`5BPlay`5D Then Begin X Died`5BPlay`5D := False; X Num_Moved_Last_Round := Num_Moved_Last_Round + 1; X end else X Died`5Bplay`5D := True; X responce`5BPlay`5D := ' '; `7B Initalise First Responce Should Not BE N Veeded `7D Xend; XFor PLay := 1 to Max_Num_PLayers do`20 X Game`5BPLay`5D := Game`5BPLay`5D + 1; XFor X := 1 To Screen_Dim_X do`20 X For Y := 1 to Screen_Dim_Y do X Screen`5BX,y`5D := '`7E'; XFor Y := 1 To Screen_Dim_Y do Begin X Screen`5B1,Y`5D := 'q'; X Screen`5BScreen_Dim_X,Y`5D := 'q'; Xend; XFor X := 1 To Screen_Dim_X Do Begin X Screen`5BX,1`5D := 'x'; X Screen`5BX,Screen_Dim_Y`5D := 'x';`20 Xend; XScreen`5B1,1`5D := 'l'; XScreen`5B1,Screen_Dim_Y`5D := 'k'; XScreen`5BScreen_Dim_X,1`5D := 'm'; XScreen`5BScreen_Dim_X,Screen_Dim_y`5D := 'j'; XHead_Sym`5B1`5D := chr(128+ord('1')); `7B Set The Bits In The Chars `7D XHead_Sym`5B2`5D := chr(128+ord('2')); XHead_Sym`5B3`5D := chr(128+ord('3')); XHead_Sym`5B4`5D := chr(128+ord('4')); XHead_Sym`5B5`5D := chr(128+ord('5')); XHead_Sym`5B6`5D := chr(128+ord('6')); XHead_Sym`5B7`5D := chr(128+ord('7')); XHead_Sym`5B8`5D := chr(128+ord('8')); X XFor Play := 1 to Max_Num_PLayers do`20 X If Not Quit`5Bplay`5D Then`20 X Screen`5BHead_X`5BPlay`5D,Head_Y`5BPlay`5D`5D := 'O'; X`7B Note If This Procedure Is Only Called When You Are Master Snake`20 X Draw Screen Should Be In The Mainlkine Before Init_pos X And The Writing Of The PLayers Pos Should Be To The Buffer`20 X And Then Written To All Who Are PLaying `7D X XDraw_screen; `20 X X`7B Pos Inital Player Positions `7D XFor Play := 1 to Max_Num_PLayers do `20 X If ( Not Quit`5BPlay`5D ) Then `20 X Writeln(at(Head_X`5BPlay`5D,Head_Y`5BPlay`5D),Head_sym`5BPlay`5D); Xend; X XProcedure Initalise_Mainline; X XVar Zero,Init_Rep,PLay,Name_pos,Game_Going : Integer; X XProcedure Verify_name(VAr Name : Name_Line ); X XVar I : INteger; X X XBegin X For I := 1 to Max_Name_length do `7B Remove All Invalid Chars From The V Name`7D X If ( Name`5Bi`5D < ' ' ) or ( Name`5Bi`5D > '`7E' ) Then Begin X Write(chr(7)); X Name`5Bi`5D := ' '; X end; Xend; X X XBegin X Esc := Chr(27); X Seed := Clock; X TT_Len := 0; X `20 X X `7B set where Each Player Starts `7D X X Init_pos_X`5B1`5D := 2; X Init_pos_Y`5B1`5D := 2; X `20 X Init_pos_X`5B2`5D := Screen_dim_x - 1; X Init_pos_Y`5B2`5D := Screen_dim_Y - 1; X `20 X Init_pos_X`5B3`5D := 2; X Init_pos_Y`5B3`5D := Screen_dim_y - 1; X `20 X Init_pos_X`5B4`5D := Screen_dim_x - 1; X Init_pos_Y`5B4`5D := 2; X `20 X Init_pos_X`5B5`5D := 2; X Init_pos_Y`5B5`5D := Screen_dim_Y div 2; X `20 X Init_pos_X`5B6`5D := Screen_dim_x - 1 ; X Init_pos_Y`5B6`5D := Screen_dim_Y div 2; X `20 X Init_pos_X`5B7`5D := Screen_dim_x div 2; X Init_pos_Y`5B7`5D := 2; X `20 X Init_pos_X`5B8`5D := Screen_dim_x div 2; X Init_pos_Y`5B8`5D := Screen_dim_Y - 1; X X Writeln(Esc,'<'); `7B Vt52 Mode `7D X Writeln(Esc,'`5B1;1H',Esc,'`5BJ'); `7B Clear Screen `7D X Init_rep := Snake_Init(You,Game_going); X You := You + 1; `20 X If Init_rep = 1 Then Begin X `7B you are the First Person to play zero all the scores `7D X For Play := 1 to Max_Num_PLayers do begin X Zero := 0; X Score_Set(Play,Zero,zero,zero); X end; X Help_Screen; X Writeln(esc,'`5B1;1H',Esc,'`5B?2l'); X Writeln(at(22,3),' Please Enter Your Name Player #',You:1); X Write(at(22,51)); X Readln(Name`5BYou`5D); X Verify_Name(Name`5BYou`5D); X Name_set(Name`5BYou`5D); X Write(at(22,3), ' Hit < Return > When Others Ready '); X Readln; X Writeln; X Write(at(22,3), ' Please Wait For Game To Start '); X Writeln; X end Else Begin X If You = 0 Then Begin X Writeln(esc,'`5B1;18H',Esc,'#3SNAKE'); X Writeln(esc,'`5B2;18H',Esc,'#4SNAKE'); X Writeln(esc,'`5B4;8H' ,Esc,'#6Sorry No Snakes Available'); X`09 Sleep(3); X goto 9999; X end else begin `7B Init_rep = 0 `7D`20 X Help_Screen; X Writeln(esc,'`5B1;1H',Esc,'`5B?2l'); X Writeln(at(22,3),' Please Enter Your Name Player # ',You:1); X Write(at(22,51)); X Readln(Name`5BYou`5D); X Verify_name(Name`5BYou`5D); X Name_set(Name`5BYou`5D); X Writeln; X Write(at(22,3), ' Please Wait For Game To Start '); X Writeln; X If Game_Going = 1 Then`20 X Snake_Game_End; X end; X end; X Game`5BYou`5D := 0; Xend `7B Initalise Mainline `7D; X XFunction Correct_Sym(Last_Move_X,Last_Move_Y,Move_X,Move_Y:Integer):Char; X XBegin `7B Calculates The Correct symbol To Write Given The Dir You Were In V `7D X Case (Last_Move_X+1) + (Last_Move_Y+1)*4 Of`20 X 6 : `7B Down `7D X Case (Move_X+1) + (Move_Y+1)*4 Of`20 X 6 : `7B Down `7D X Correct_Sym := 'x'; X 9 : `7B Right `7D X Correct_Sym := 'm'; X 1 : `7B Left `7D X Correct_Sym := 'j'; X 4 : `7B Up Note : This Is Poss On First Move `7D X Correct_Sym := 'x'; X end `7B Case `7D; X 4 : `7B Up `7D X Case (Move_X+1) + (Move_Y+1)*4 Of`20 X 6 : `7B Down `7D X Correct_Sym := 'x'; X 4 : `7B Up `7D X Correct_Sym := 'x'; `20 X 9 : `7B Right `7D X Correct_Sym := 'l'; X 1 : `7B Left `7D X Correct_Sym := 'k'; `20 X end `7B Case `7D; X `20 X 9 : `7B Right `7D X Case (Move_X+1) + (Move_Y+1)*4 Of`20 X 6 : `7B Down `7D X Correct_Sym := 'k'; `20 X 4 : `7B Up `7D X Correct_Sym := 'j'; `20 X 9 : `7B Right `7D X Correct_Sym := 'q'; X 1 : `7B Left `7D X Correct_Sym := 'q'; `20 X end `7B Case `7D; X X 1 : `7B Left `7D X Case (Move_X+1) + (Move_Y+1)*4 Of`20 X 9 : `7B Right `7D X Correct_Sym := 'q'; X 6 : `7B Down `7D X Correct_Sym := 'l'; `20 X 4 : `7B Up `7D X Correct_Sym := 'm'; `20 X 1 : `7B Left `7D X Correct_Sym := 'q'; `20 X end `7B Case `7D; X X end `7B Case `7D; Xend; `7B Correct Sym `7D X X`5BGLOBAL`5D Function Add_head( Var Responce : Player_responce ):Integer; X XVar Play, Num_Moved, Dir_X, Dir_Y, Pos_x, Pos_Y : Integer; X X X XProcedure Remove_tail( Var STail_X , STail_Y : Integer ); X XVar Last_X,Last_Y : Integer; X XBegin `7B removes the Tail of the snake whose tail is at StailX,Y `7D X`7B The Character To Move is determined by the Char at the tail X and if a character joins up to it `7D X X Last_X := STail_X; X Last_Y := STail_Y; X Pos(STail_X,STail_Y,'`7E'); X Case Screen`5BSTail_X,STail_Y`5D of`20 X 'l' : If Screen`5BStail_X,STail_Y+1`5D In `5B'k','j','q'`5D Then`20 X STail_Y := STail_Y + 1 X Else X STail_X := STail_X + 1; X 'k' : If Screen `5BSTail_X,STail_Y-1`5D In `5B'l','m','q'`5D Then`2 V0 X STail_Y := STail_Y - 1 X Else X Stail_X := STail_X + 1 ; X 'm' : If Screen`5BSTail_X,STail_Y+1`5D In `5B'k','j','q'`5D Then X Stail_Y := STail_Y + 1 X Else X Stail_X := Stail_X - 1 ; X 'j' : If Screen`5BSTail_X,STail_Y-1`5D In `5B'm','l','q'`5D Then`20 X STail_Y := STail_Y - 1 X Else X STail_X := STail_X - 1; X 'x' : If Screen`5BSTail_X-1,STail_Y`5D In `5B'l','k','x'`5D Then`20 X STail_X := STail_X - 1 X Else X STail_X := STail_X + 1; X 'q' : If Screen`5BSTail_X,STail_Y - 1 `5D In `5B 'l','m','q'`5D The Vn`20 X STail_Y := STail_Y - 1 X Else X STail_Y := STail_Y + 1; X end `7B CAse `7D; X Screen`5BLast_X,Last_Y`5D := '`7E'; Xend `7B remove_Tail`7D; X X XProcedure Remove_Players_tail( play : Integer ); X XVar X,Y : Integer; X XBegin `7B Removed Odd Players Tails Of Play = 1 Even If 2 `7D X While Play <= Max_PLayer_Number do Begin X If Not Died`5BPlay`5D Then `20 X Remove_tail(Tail_X`5BPLay`5D,Tail_Y`5BPLay`5D); X Play := Play + 2; X end; Xend; X X XProcedure Add_This_Players_Head; X Xbegin X If Not Quit`5BPlay`5D And (Ord(Responce`5BPLay`5D) = 0 ) Then begin X Died`5BPLay`5D := True; `7B If PLayer quit Then`20 X Quit`5BPLay`5D := True; Initalise all Variables `7D X Game`5BPlay`5D := 0; X Score`5BPlay`5D := 0; X Games_Won`5BPLay`5D := 0; X Score_Set(Play,Score`5BPlay`5D,Game`5BPLay`5D,Games_Won`5BPLay`5D); X end else`20 X If Not Died`5BPlay`5D Then Begin X Dir_X := Move_X`5BPlay`5D; X Dir_Y := Move_Y`5BPLay`5D; X`09 Pos_X := Head_X`5BPlay`5D; X Pos_Y := Head_Y`5BPlay`5D; X `7B Change Direction Of The Position You Move To is Not A Wall ie = V '.' `7D X Case Ord(responce`5BPlay`5D) Of`20 X 8 : If Screen`5BPos_x-1,Pos_Y`5D = '`7E' Then Begin X Dir_X := -1 ; X Dir_Y := 0 ; `7B Moving Up `7D X end; X 2 : If Screen`5BPos_X+1,Pos_Y`5D = '`7E' Then Begin X Dir_X := 1; X Dir_Y := 0; `7B Moving Down `7D X end; X 4 : If Screen`5BPos_X,Pos_Y-1`5D = '`7E' Then Begin X Dir_X := 0; `7B Moving Left `7D X Dir_Y := -1; X end; X 6 : If Screen`5BPos_X,Pos_Y+1`5D = '`7E' Then Begin X Dir_X := 0; `7B Moving Right `7D X Dir_Y := 1; X end; X otherwise `7B Do Nothing Same Dir As Before `7D X end `7B Case `7D; X `7B Given LAst Direction Or New Direction `7D X If Screen`5BPos_X + Dir_X , Pos_Y + Dir_Y `5D = '`7E' Then Begin `2 V0 X`09 `7B Going into a Blank square ok to move `7D X Num_Moved := Num_Moved + 1; X Screen`5BPos_X ,Pos_Y `5D :=`20 X Correct_sym(Move_X`5BPlay`5D,Move_Y`5BPLay`5D,Dir_X,Dir_Y) V; X pos(Pos_X,Pos_Y,Screen`5BPos_X,Pos_Y`5D); X Pos_X := Pos_X + Dir_X; X Pos_Y := Pos_Y + Dir_Y; X Screen`5BPos_X,Pos_Y`5D := 'O'; X Pos(Pos_X,Pos_Y,Head_Sym`5BPLay`5D); X end else begin `7B You HAve Died Hit Into A Non Blank Square `7D X Died`5BPlay`5D := True; X If Num_PLayers <> Num_Moved_Last_Round Then `20 X Score`5BPlay`5D := Score`5BPlay`5D +`20 X (( Num_PLayers - Num_Moved_Last_Round + 1 )**2 * 100 ) V`20 X div ( NUm_Players**2); X pos(Pos_X,Pos_Y,Correct_sym(Move_X`5BPlay`5D,Move_Y`5BPLay`5D,Di Vr_X,Dir_Y)); X Pos_X := Pos_X + Dir_X; X Pos_Y := Pos_Y + Dir_Y; X`09 Snake_Dead(play);`20 X end; X Move_X`5BPlay`5D := Dir_X; X Move_Y`5BPLay`5D := Dir_Y; X`09 Head_X`5BPlay`5D := pos_X; X Head_Y`5BPlay`5D := Pos_Y; X end; Xend; X Xbegin X Num_Moved := 0; `7B Iniotalise Counter For The Number Who Move Vd `7D X If Players_reMoving = 1 Then Begin `7B If 1 Then Loop Clockwise `7D X For Play := 1 to Max_Player_number do`20 X add_This_Players_head; X Remove_players_tail(1); `7B Remove Odd Players Tail `7D X PLayers_ReMoving := 2; `7B Next Round Shall remove Even V Ones `7D X end else`20 X If Players_removing = 2 Then Begin X For Play := Max_Player_Number downto 1 do`20 X add_This_Players_head; `7B Go Clockwise In Updatin Vg `7D X Remove_Players_tail(2); X PLayers_ReMoving := 1; X end else begin X For Play := Max_Player_Number downto 1 do `7B First Few Moves Don't V remove Tail `7D X add_This_Players_head; `7B Go Clockwise In Updatin Vg `7D X Players_removing := Players_removing + 1; X end; X If Num_Moved <= 1 Then Begin `7B Ie There IS Only 1 or 0 V PLayers Left `7D X For PLay := 1 to Max_player_Number do Begin X`09If Not Quit`5BPlay`5D Then Begin X If Not Died`5BPLay`5D Then Begin X Score`5BPLay`5D := Score`5BPlay`5D + 100; `7B One Hundred V If You Last Left `7D X Games_Won`5BPLay`5D := Games_Won`5BPLay`5D + 1; X end; X Score_set(Play,Score`5BPlay`5D,Game`5BPlay`5D,Games_Won`5BPLay`5 VD); X end; X end; X Add_head := 0; `7B Return 0 To Stop The Game `7D X end else`20 X Add_Head := 1; `7B 1 To Comtinue `7D X Num_Moved_Last_Round := Num_Moved; X Break_Buff; `7B does not write the buffer just says To`20 X Write this buffer to all the players when add_head exits V `7D Xend `7B add_Head`7D; X X XProcedure Snake_PLay;extern; X X XBegin `7B Mainline `7D X LineLimit(Output,MaxInt); X Initalise_Mainline; X While True Do Begin +-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+- -+-+-+-+-+-+-+-+ START OF PART 5 -+-+-+-+-+-+-+-+ X Initalise_Positions; `7B initalises pos Only relavent for master V snake `7D X Snake_Play; `7B Calls Add_head with the Moves of the pla Vyers until add_head returns 1 ( end of game ) `7D X Draw_Scores; X Snake_Game_End; `7B Syncs all players Together `7D X end; X9999 :`20 X Writeln(esc,'<'); Xend. $ CALL UNPACK SNAKEP.PAS;1 141985560 $ v=f$verify(v) $ EXIT $ ! if f$envi("DEFAULT") .nes. "PUBLIC:[PELIT.TEMP]" then exit $ on error then goto end $loop: $ set def public:[pelit.tmp] $ p0 = f$ele(1,"]",f$sear("*.1;")) - ".1;1" $ if p0 .eqs. "]" then goto end $ ws p0 $ crea/dir <-.'p0'> $ copy 'p0'.* <-.'p0'>'p0'.share $ copy <-.'p0'>'p0'.share <-.share> $! set acl/acl=(id=gamekeeper,acc=d) 'p0'.* $ del 'p0'.*. $! cd <-.'p0> $! @<-.'p0>'p0'.share $! cd <-.temp> $goto loop $end: $ ws "Valmis !!" * Program SNAKE by Rex Croft and Murray Speight (1982). * For compilation you will need file UTIL.OLB * which can be found in the LIBRARY directory. * SNAKE.$PACKAGE SNAKE.1 SNAKE.2 SNAKE.3 SNAKE.4 SNAKE.5 $! ------------------ CUT HERE ----------------------- $ v='f$verify(f$trnlnm("SHARE_VERIFY"))' $! $! This archive created by VMS_SHARE Version 7.2-007 22-FEB-1990 $! On 7-APR-1993 18:58:18.88 By user MASTER $! $! This VMS_SHARE Written by: $! Andy Harper, Kings College London UK $! $! Acknowledgements to: $! James Gray - Original VMS_SHARE $! Michael Bednarek - Original Concept and implementation $! $!+ THIS PACKAGE DISTRIBUTED IN 5 PARTS, TO KEEP EACH PART $! BELOW 30 BLOCKS $! $! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER $! AND EXECUTE AS A COMMAND PROCEDURE ( @name ) $! $! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING: $! 1. BUILD.COM;1 $! 2. SNAKE.MAR;1 $! 3. SNAKE.SCN;1 $! 4. SNAKEH.FOR;1 $! 5. SNAKEP.PAS;1 $! $set="set" $set symbol/scope=(nolocal,noglobal) $f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID")) $e="write sys$error ""%UNPACK"", " $w="write sys$output ""%UNPACK"", " $ if f$trnlnm("SHARE_LOG") then $ w = "!" $ ve=f$getsyi("version") $ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START $ e "-E-OLDVER, Must run at least VMS 4.4" $ v=f$verify(v) $ exit 44 $UNPACK: SUBROUTINE ! P1=filename, P2=checksum $ if f$search(P1) .eqs. "" then $ goto file_absent $ e "-W-EXISTS, File ''P1' exists. Skipped." $ delete 'f'* $ exit $file_absent: $ if f$parse(P1) .nes. "" then $ goto dirok $ dn=f$parse(P1,,,"DIRECTORY") $ w "-I-CREDIR, Creating directory ''dn'." $ create/dir 'dn' $ if $status then $ goto dirok $ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped." $ delete 'f'* $ exit $dirok: $ w "-I-PROCESS, Processing file ''P1'." $ if .not. f$verify() then $ define/user sys$output nl: $ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1' PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET( SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:= CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b)); LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION( BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1); IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE; MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1; ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")= 1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF"; POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r); ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1; COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE, "output_file"));ENDPROCEDURE;Unpacker;QUIT; $ delete/nolog 'f'* $ CHECKSUM 'P1' $ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT $ e "-E-CHKSMFAIL, Checksum of ''P1' failed." $ ENDSUBROUTINE $START: $ create 'f' X$ MACRO SNAKE X$ PASCAL SNAKEP X$ FORTRAN SNAKEH X$! X$ LINK/NOTRACE SNAKE,SNAKEP,SNAKEH,UTIL/LIB X$ DELETE/NOCONFIRM *.OBJ;* X$ EXIT $ CALL UNPACK BUILD.COM;1 1346713570 $ create 'f' X`09.title`09SNAKEM`09Snake Game X;+ X;`09or`09TANKM`09Tank Game X;`09if $$TANK is defined X;- X X`09$dibdef X`09$iodef X`09$qiodef X`09$secdef X`09$jpidef X;`09$ssdef Xesc`09`09= 27 X Xsnake`09`09= 8`09`09; number of snakes X X;`09meaning of event flags in cluster 2 X Xflag$v_master`09= 0`09`09; set if a master snake exists Xflag$v_read`09= 1`09`09; set if all snakes should read command Xflag$v_update`09= 2`09`09; set if all snakes should update screen Xflag$v_game`09= 3`09`09; set if game is in progress Xflag$v_endofgame= 4`09`09; set if we have reached the end of the game Xflag$v_synch`09= 5 Xflag$v_done`09= 8`09`09; set if operation (read,update) is complete X Xcheck_timer`09= 13`09`09; check timer id X X X`09.psect`09$rodata`09nowrt, noexe, shr, pic, long X Xttname_descr: X`09.ascid`09/TT/ X Xmbxcnv: X`09.ascid`09/_MBA!UW:/`09; convert mbx unit number to physical name X Xmbxbuf_descr: X`09.word`09mbxbuf_siz, 0 X`09.long`09mbxbuf X Xdibbuf_descr: X`09.word`09dib$k_length, 0 X`09.long`09dibbuf X X`09.align long Xsnake_desc_2: X.if ndf $$tank X`09.ascid`09/SNAKE_1/`09`09; name of snake event flags X.iff X`09.ascid`09/TANK_1/ X.endc X X`09.align`09long Xsnake_map_name: X.if ndf $$tank X`09.ascid`09/SNAKE_DATA/ X.iff X`09.ascid`09/TANK_DATA/ X.endc X Xtext = . X`09.ascii`09'<'`09`09; enter ANSI mode X`09.ascii`09'(B'`09`09; select ascii character set X`09.ascii`09'`5B2J'`09`09; erase entire screen X`09.ascii`09'`5B1;1H'`09`09; jump to top left corner X`09.ascii`09<10>`09`09`09; linefeed X.if ndf $$tank X`09.ascii`09'#3 SNAKE' ; double-height top half X.iff X`09.ascii`09'#3 TANK' X.endc X`09.ascii`09<13><10> X.if ndf $$tank X`09.ascii`09'#4 SNAKE' ; double-height bottom half X.iff X`09.ascii`09'#4 TANK' X.endc X`09.ascii`09<13><10><10> X`09.ascii`09'#6 Thank you for playing' X`09.ascii`09<13><10><10> Xtext_len = . - text X`09.align`09long Xtext_end_game: X`09.long`092 X`09.long`09text X`09.address 10$ X10$:`09.long`09text_len X Xtext = . X`09.ascii`09<13><10><10> X`09.ascii`09'Game aborted because master ' X.if ndf $$tank X`09.ascii`09'snake' X.iff X`09.ascii`09'tank' X.endc X`09.ascii`09' quitted'<13><10><10> Xtext_len = . - text X`09.align`09long Xtext_abort: X`09.long`092 X`09.long`09text X`09.address 10$ X10$:`09.long`09text_len X Xtext = . X`09.ascii`09 'Y' <31+24> <31+1>`09; col 1, row 24 X`09.ascii`09 'G'`09`09`09; exit graphics X`09.ascii`09<7> ' Please wait for next game ...' X`09.ascii`09 'F'`09`09`09; enter graphics Xtext_len = . - text X`09.align`09long Xtext_wait: X`09.long`092 X`09.long`09text X`09.address 10$ X10$:`09.long`09text_len X X`09.align`09long Xusername_jpi: X`09.word`0912, jpi$_username X`09.address username_buf X`09.address username_siz X`09.long`090 X X`09.align`09long Xstart_wait: X`09.long`09-10000000*5, -1`09`09; wait 5 seconds Xsecond_1: X`09.long`09-10000000*1, -1`09`09; wait 1 second Xsecond_2: X`09.long`09-10000000*2, -1`09`09; wait 2 seconds Xupdate_wait: X`09.long`09-100000*33, -1`09`09; wait 33/100 ths of a second Xcheck_wait: X`09.long`09-10000000*4, -1`09`09; wait 2 seconds for checking Xvalid_move: X`09.long`09`5EB101110100`09`09; valid moves are 2,4,6,8 and 5!! Xstart_direction: X.if ndf $$tank X`09.byte`092, 8, 2, 8, 2, 8, 6, 4`09; initial move directions for snake X.iff X`09.byte`096, 4, 4, 6, 2, 8, 6, 4`09; for tank X.endc X`09.align`09long Xadd_head_par: X`09.long`091`09`09`09; parameter list to Pascal routine X`09.address move`09`09`09; each players move Xupdate_par: X`09.long`092 X`09.address outbuf X`09.address screen_len Xupdate_par2:`09`09`09; if we have died, then there is no head X`09.long`092`09`09; to change to a diamond, so write screen X`09.address screen_buf`09; update directly from global memory. X`09.address screen_len X X`09.psect`09$rwbuf`09wrt, noexe, noshr, pic, page X Xmbxname_len = 16 Xmbxname:`09`09`09; room to hold the physical mbx name X`09.blkb`09mbxname_len Xmbxname_descr: X`09.word`09mbxname_len, 0 X`09.long`09mbxname Xmbxiosb: X`09.long`090,0 Xmbxbuf_siz = 32 Xmbxbuf: X`09.blkb`09mbxbuf_siz X Xdibbuf: X`09.blkb`09dib$k_length X X`09.align`09long Xttiosb: X`09.long`090,0 X Xttbuf_siz = 128 Xttbuf: X`09.blkb`09ttbuf_siz X`09.align`09page Xoutbuf_siz = 512 Xoutbuf:: X`09.blkb`09outbuf_siz X X X;snake_fab: X;.if ndf $$tank X;`09$fab`09fnm=, fop=,- X;`09`09fac=, shr= X;.iff X;`09$fab`09fnm=, fop=,- X;`09`09fac=, shr= X;.endc Xmap_range: X`09.address share_data X`09.address share_data+<512*3> Xret_range: X`09.long`090, 0 X X X`09.psect`09$sharedata wrt, noexe, shr, pic, page Xshare_data: X Xgame_count: X`09.long`09`09`09; count of number of games played Xmaster_flag: X`09.long`09`09`09; = 1 if we are master snake Xabort: X`09.long`09`09`09; = 1 if all snakes should abort Xplayer_bits: X`09.long`09`09`09; bit set if that snake is playing Xplayers: X`09.long`09`09`09; bit set if that snake is reserved Xother_players: X`09.long`09`09`09; used by master snake to wait for other X`09`09`09`09; snakes to indicate operation completed Xmove_count: X`09.long`09`09`09; incremented every move. Used for detecting X`09`09`09`09; other snakes hanging the game Xgame_going: X`09.long`09`09`09; <> 0 if a game is going Xyou_just_died: X`09.long`09`09`09; bit I set if snake I just died Xseed: X`09.long`09`09`09; random number seed Xstart_position: X`09.blkl`09snake`09`09; position of starting (1-8) X; X;`09`095 X; 1`09+---------------+ 3 X;`09`7C`09`09`7C X;`09`7C`09`09`7C X; 7`09`7C`09`09`7C 8 X;`09`7C`09`09`7C X;`09`7C`09`09`7C X; 4`09+---------------+ 2 X;`09`096 X; Xscore: X`09.blkl`09snake`09`09; players' score Xn_games: X`09.blkl`09snake`09`09; # of games each player has played Xwins: X`09.blkl`09snake`09`09; # of wins for each player Xplayer_pos: X`09.blkl`09snake`09`09; starting position of each snake X`09.align`09quad Xmove: X`09.blkb`09snake`09`09; each snakes move Xname_size = 32 Xname: X`09.blkb`09name_size * snake ; each snakes name (32 chars long) X. = . + 512 - < . - share_data > X`09.align`09long Xscreen_len: X`09.long`09`09`09; # chars to be output Xscreen_buf: X`09.blkb`09508`09`09; buffer containing screen update X. = . + <512*4> - < . - share_data > X X X`09.psect`09$rwdata`09wrt, noexe, noshr, pic, long X Xttchan: X`09.word Xmbxchan: X`09.word Xdata_ready: X`09.word Xmaster: X`09.word`09`09`09; = 1 if we are master snake Xcontrol_c_flag: X`09.word`09`09`09; non zero if `5EC typed Xdead: X`09.word`09`09`09; bit I set if snake I just died X`09.align`09long Xcluster_2: X`09.long Xcluster_3: X`09.long Xplayer: X`09.long Xplayer_efn:`09`09`09; my player efn in cluster 2 X`09.long Xcurrent_players: X`09.long Xchars_left:`09`09`09; # of chars left in buffer X`09.long Xchar_pointer: X`09.long`09`09`09; address of next character Xlast_move_count: X`09.long Xusername_buf: X`09.blkb`0912 Xusername_siz: X`09.long X Xoutbuf_qio: X`09$qio`09func=io$_writevblk!io$m_noformat,- X`09`09p1=outbuf Xoutput_qio: X`09$qio`09func=io$_writevblk!io$m_noformat X Xread_qio: X`09$qio`09func=io$_readvblk!io$m_timed!io$m_noecho!io$m_nofiltr,- X`09`09iosb=ttiosb,- X`09`09p1=ttbuf, p2=ttbuf_siz, p3=0`09; wait time = 0 X Xexit_block:`09`09`09; exit handler block X`09.long X`09.address snake_exit X`09.long`091`09`09; 1 argument X`09.address 10$ X10$:`09.long`09`09`09; exit reason X X X`09.psect`09$code`09nowrt, exe, shr, pic X X`09.entry`09- XTTINIT, `5Em<> X;+ X; Create a mailbox. Assign a channel to terminal with an associated mailbox V. X;- X`09$crembx_s`09chan=mbxchan, promsk=#`5ExFF00 X`09bsbw`09`09error X`09$getchn_s`09chan=mbxchan, pribuf=dibbuf_descr X`09bsbw`09`09error X`09$fao_s`09`09ctrstr=mbxcnv, outbuf=mbxname_descr,- X`09`09`09outlen=mbxname_descr, p1=dibbuf+dib$w_unit X`09$assign_s`09devnam=ttname_descr, chan=ttchan, - ; acmode=#`5ExFF00, X`09`09`09mbxnam=mbxname_descr X`09blbc`09r0, 100$ X`09movw`09ttchan, outbuf_qio+qio$_chan`09`09;store channel # X`09movw`09ttchan, output_qio+qio$_chan`09`09;store channel # X`09movw`09ttchan, read_qio+qio$_chan`09`09;store channel # X`09$qiow_s`09func=#io$_setmode!io$m_ctrlcast, chan=ttchan,- X`09`09p1=control_c X`09ret X100$: X`09bsbw`09error X`09ret X X`09.entry`09- XTT1CHAR,`09`5Em<> X`09clrb`09ttbuf X`09$qiow_s`09func=#io$_readvblk!io$m_timed!io$m_noecho!io$m_nofiltr,- X`09`09chan=ttchan, iosb=ttiosb,- X`09`09p1=ttbuf, p2=#1, p3=#0`09; wait time = 0 X`09cvtbl`09ttbuf, r0 X`09cmpb`09r0, #13`09`09`09; is it ? X`09bneq`09100$ X`09clrb`09data_ready X100$:`09ret X XTTREAD:: X`09blbs`09control_c_flag, 10$ X`09tstl`09chars_left`09`09; have we used all characters ? X`09bgtr`0950$`09`09`09; no --> 50$ X`09bbsc`09#0, data_ready, 20$`09; check if input ready X5$:`09mnegl`09#1, r0`09`09`09; no characters read X`09rsb`09`09`09`09; no X10$: X`09clrl`09r0`09`09`09; on `5EC return move 0 = quit X`09rsb X20$: X`09$qiow_g read_qio X`09blbc`09r0, 5$`09`09`09; error X; X;`09$qiow_s`09func=#io$_writevblk,chan=ttchan,-`09; debug write X;`09`09p1=ttbuf, p2=ttiosb+2, p4=#`5Ex1000 X X`09movzwl`09ttiosb+2, chars_left`09`09; # chars read X`09movab`09ttbuf, char_pointer`09`09; store address of character X50$: X`09decl`09chars_left X`09movzbl`09@char_pointer, r0`09`09; get next char X`09incl`09char_pointer`09`09`09; point to next X`09subb2`09#`5EA/0/, r0`09`09`09; convert from ascii to binary X`09blss`09200$`09`09`09`09; invalid command X`09cmpb`09r0, #9 X`09bgeq`09150$`09`09`09`09; invalid command (maybe quit) X`09bbc`09r0, valid_move, 200$`09`09; invalid command X.if df $$tank X`09tstl`09chars_left`09`09`09; any chars left ? X`09bleq`09100$`09`09`09`09; no --> 100$ X`09cmpb`09@char_pointer, #`5EA/5/`09`09; is next command fire ? X`09bneq`09100$`09`09`09`09; no --> 100$ X`09incl`09char_pointer X`09decl`09chars_left X`09bisb2`09#`5EB10000, r0`09`09`09; add 16 to indicate fire X.endc X100$: X`09rsb X150$: X`09cmpb`09r0, #`5EA/e/-`5EA/0/`09`09; was an "e" typed ? X`09beql`09180$ X`09cmpb`09r0, #`5EA/E/-`5EA/0/`09`09; was an "E" type ? X`09bneq`09200$ X180$: X`09clrl`09r0`09`09`09`09; quit is move = 0 X`09rsb X200$: X`09mnegl`09#1, r0`09`09`09`09; no move given X`09rsb X X`09.entry`09- XMBXREAD,`09`5Em<> X;+ X; This is an AST routine which executes when the mailbox record has been rea Vd. X; The record itself is a status message which is assumed to say that X; unsolicited data is available at the terminal X;- X`09blbc`09mbxiosb, 100$`09`09; on error, dont re-que read X;`09we could have SS$_CANCEL or SS$_ABORT from the $CANCEL in the X;`09exit handler X`09movb`09#1, data_ready`09`09; indicate data is there X`09bsbw`09queue_mbxread`09`09; queue another read request X100$: X`09ret X XQUEUE_MBXREAD: X`09$qio_s`09efn=#2, func=#io$_readvblk, chan=mbxchan, iosb=mbxiosb,- X`09`09astadr=mbxread,- X`09`09p1=mbxbuf, p2=#mbxbuf_siz X`09blbc`09r0, 100$ X`09rsb X100$: X`09bsbw`09error X`09rsb X XTTWRITE:: X;+ X;`09bsbw`09ttwrite X;`09r3 contains length of buffer to write X;`09the buffer is outbuf X;- +-+-+-+-+-+-+-+- END OF PART 1 +-+-+-+-+-+-+-+- -+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+ X`09movl`09r3, outbuf_qio+qio$_p2`09`09; store length of buffer X`09$qiow_g`09outbuf_qio X`09blbc`09r0, 100$ X`09rsb X100$: X`09bsbw`09error X`09rsb X X X`09.entry`09- Xsnake_screen, `5Em X;+ X;`09CALL SNAKE_SCREEN( array, length ) X;`09BYTE ARRAY( LENGTH ) X;`09copies string to update screen into shared memory X;- X`09movl`09@8(ap), r0`09`09; get length X`09movl`09r0, screen_len`09`09; store length X`09movc3`09r0, @4(ap), screen_buf`09; copy text X`09ret X X`09.entry`09- Xsnake_write, `5Em<> X;+ X;`09CALL SNAKE_WRITE( array, length ) X;`09BYTE ARRAY( LENGTH ) X;`09writes buffer to terminal in noformat mode X;- X`09movl`094(ap), output_qio+qio$_p1`09; store address of buffer X`09movl`09@8(ap), output_qio+qio$_p2`09; store length of buffer X`09$qiow_g`09output_qio X`09blbc`09r0, 100$ X`09ret X100$: X`09bsbw`09error X`09ret X X`09.entry`09- Xsnake_dead, `5Em<> X;+ X;`09CALL SNAKE_DEAD( player # ) X;- X`09subl3`09#1, @4(ap), r0`09`09`09; get # of snake who died X`09bbss`09r0, you_just_died, 100$`09`09; set flag saying he died X100$:`09ret X X X`09.entry - XCANCELTYPEAHEAD, `5Em<> X`09clrl`09r0 X`09tstw`09ttchan`09`09; check channel is open X`09beql`09100$ X`09$qiow_s`09func=#io$_readvblk!io$m_purge!io$m_timed,- X`09`09chan=ttchan, p1=ttbuf`09; do read with 0 length buffer (p2) X100$:`09ret`09`09`09; return with status in r0 X XERROR: X`09blbs`09r0, 100$ X`09pushl`09r0 X`09calls`09#1, G`5Elib$signal X100$: X`09rsb X X`09.entry`09- Xcontrol_c, `5Em<> X`09movb`09#1, control_c_flag X`09ret X X X`09.page X`09.entry`09- XSNAKE_INIT, `5Em`09`09`09`09; snake game X;+ X;`09I = SNAKE_INIT( player # , game ) X;`09returns I = 1 if you are master snake. X;`09returns your player # as a integer X;`09returns game = 1 if there is a game in progress X;- X X`09calls`09#0, G`5Ettinit`09`09`09; open terminal X; X`09$ascefc_s efn=#64, name=snake_desc_2`09; associate event flag cluster X`09bsbw`09error X; X;`09$open`09fab=snake_fab`09`09`09; open section file X;`09bsbw`09error X X`09$deltva_s inadr=map_range`09`09; delete memory were global X`09bsbw`09error`09`09`09`09; memory will be mapped X X`09$crmpsc_s inadr=map_range, flags=#sec$m_gbl!sec$m_wrt!sec$m_pagfil, - X`09`09gsdnam=snake_map_name, -`09; chan=snake_fab+fab$l_stv,- X`09`09pagcnt=#4 X`09bsbw`09error X X`09cmpl`09r0, #ss$_created`09`09; are we first to map section X`09bneq`0950$`09`09`09`09; no X`09movab`09share_data+4, r3 X`09movc5`09#0, (r3), #0, #512-4, (r3)`09; clear everything except count X`09$clref_s efn=#flag$v_game+64`09`09; say not game X`09movl`09#39814571, seed`09`09`09; init random n.g. seed X`09movl`09#snake, r0`09`09`09; 8 snakes X20$: X`09movl`09r0, start_position-4`5Br0`5D`09; init start position X`09sobgtr`09r0, 20$ X50$: X`09blbc`09abort, 60$`09`09`09; if not abort --> 60$ X`09callg`09text_abort, snake_write X`09$exit_s #1 X60$: X`09bsbw`09queue_mbxread`09`09`09; start terminal read X; X`09bbss`09#0, master_flag, 100$`09`09; see if a master snake exists X`09`09`09; this should be interlocked on a multi-processor X;+ X; We will have to be the master snake X;- X`09movb`09#1, master`09`09`09; indicate we are master snake X`09$setef_s efn=#7`09`09`09`09; set for first call X100$: X; X`09clrl`09r1`09`09`09`09; start at player 0 (bit0=1) X150$: X`09bbcs`09r1, players, 200$`09`09; see if this snake is free X`09incl`09r1`09`09`09`09; go to next snake X`09cmpl`09r1, #snake`09`09`09; have we checked all snakes? X`09blss`09150$`09`09`09`09; no --> 150$ X`09mnegl`09#1, r1`09`09`09`09; player = -1 means none X200$: X`09movl`09r1, player`09`09`09; store my snake number (0-7) X`09movl`09player, @4(ap)`09`09`09; and return it X500$: X`09movzbl`09game_going, @8(ap)`09`09; return game going flag X X`09movl`09r1, r3 X`09$getjpi_s itmlst=username_jpi`09`09; get our username X`09mull2`09#name_size, r3`09`09`09; get offset to start of name X`09blss`09600$`09`09`09`09; no snakes available X`09movc5`09username_siz, username_buf, #`5Ea/ /, #name_size, name(r3) X`09`09`09`09`09`09; copy username X600$: X`09$dclexh_s desblk=exit_block`09`09; declare exit handler X`09bsbw`09error X X`09movzbl`09master, r0`09`09`09; return master snake status X`09ret X Xmaster_wait: X;+ X; master snake has to wait some time for other snakes to start playing X; called from SNAKE_START X;- X`09incl`09game_count`09`09`09; say another game being played X220$:`09clrb`09player_bits`09`09`09; no other players X`09bbss`09player, player_bits, 400$`09; say I am playing X400$: X`09$clref_s efn=#flag$v_synch+64 X;+ X;`09randomise starting positions X;- X`09moval`09start_position, r4`09`09; starting position numbers X`09movl`09#1, r2`09`09`09`09; snake index (start at 1) X500$: X`09pushal`09seed`09`09`09`09; random number seed X`09calls`09#1, G`5Emth$random`09`09; random real in r0 X`09addl3`09#1, r2, r3`09`09`09; snake + 1 X`09cvtlf`09r3, r3`09`09`09`09; as real X`09mulf2`09r3, r0`09`09`09`09; get snake to change pos with X`09cvtfl`09r0, r0 X`09movl`09(r4)`5Br0`5D, r1`09`09`09; swap these positions X`09movl`09(r4)`5Br2`5D, (r4)`5Br0`5D X`09movl`09r1, (r4)`5Br2`5D X`09aobleq`09#7, r2, 500$ X; X;`09moval`09start_position, r4 X`09movab`09move, r3 X`09movl`09#snake, r2`09`09`09; number of snakes X600$: X`09movl`09(r4)+, r0`09`09`09; get start position (1-8) X`09movb`09start_direction-1`5Br0`5D, (r3)+`09; copy start direction X`09sobgtr`09r2, 600$ X; X`09$setimr_s efn=#flag$v_game+64,-`20 X`09`09`09daytim=second_1`09`09; wait a time for other snakes X`09$waitfr_s efn=#flag$v_game+64`09`09; say that a game is going X`09movb`09#1, game_going`09`09`09; say game going X`09$clref_s efn=#flag$v_endofgame+64`09; say not end of game X`09$setef_s efn=#7`09`09`09`09; sets event flag for first X`09`09`09`09`09`09; call to snake_wait X`09$setimr_s efn=#flag$v_synch+64,-`09`09 X`09`09`09 daytim=start_wait X`09$waitfr_s efn=#flag$v_synch+64 X`09; this allows other snakes to set bit saying they are playing X X`09rsb X X`09.entry`09- XSNAKE_START, `5Em X;+ X;`09CALL SNAKE_START( PLAYERS , START_POSITION ) X;`09INTEGER PLAYERS, START_POSITION(8) X;`09waits 5? seconds for other players to run game X;`09The master snake is assumed to have waited some additional time X;`09Returns PLAYERS, bit I <> 0 if that player is active X;`09START_POSITION(I) is the starting location of snake I, (1-8) X;- X`09blbc`09master, 500$`09`09`09; are we master snake ? X`09bsbw`09master_wait X`09brb`09800$ X200$: X`09$exit_s #1`09`09`09`09; game aborted so stop X500$: X`09$waitfr_s efn=#flag$v_game+64`09`09; wait until a game starts X`09blbs`09abort, 200$`09`09`09; if game stopped --> 200$ X`09bbss`09player, player_bits, 600$`09; say I am playing X600$:`09$waitfr_s efn=#flag$v_synch+64`09`09; synchronise X`09blbs`09abort, 200$`09`09`09; if game stopped --> 200$ X800$: X`09movzbl`09player_bits, r4`09`09`09; get player bits X`09ashl`09#flag$v_done, r4, other_players ; used by master snake X`09movl`09r4, @4(ap)`09`09`09; store player bits X`09clrl`09chars_left`09`09`09; cancel type ahead X`09clrb`09data_ready`09`09`09; make us do a read X`09$qiow_g read_qio`09`09`09; clear out type-ahead X;`09return starting positions X`09moval`09start_position, r0`09`09; address of new positions X`09movl`098(ap), r2`09`09`09; address of where to put them X`09movl`09#snake, r1`09`09`09; number of snakes X900$: X`09movl`09(r0)+, (r2)+ X`09sobgtr`09r1, 900$ X X`09mnegl`09#1, last_move_count`09`09; invalidate last counter X X`09ret X X XSNAKE_WAIT:: X;+ X;`09BSBW SNAKE_WAIT X; `09wait until we are told to read players command(s) X;- X`09blbs`09master, 200$`09`09`09; are we master snake ? X`09$waitfr_s efn=#flag$v_read+64`09`09; if not then wait for flag X`09rsb X200$:`09; master snake waits and then sets flag for all players X`09$cantim_s reqidt=#check_timer`09`09; cancel checking timer X`09$waitfr_s efn=#7`09`09`09; wait for previous timer X`09$setimr_s efn=#8, daytim=check_wait, - X`09`09astadr=check_ast, reqidt=#check_timer ; set off checking timer X`09$setimr_s efn=#7, daytim=update_wait X`09$clref_s efn=#flag$v_update+64`09`09; clear next flag to wait on X`09movl`09#flag$v_done+64, r2`09`09; clear each players done flag X`09$clref_s efn=r2`09`09`09`09; player 0 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2 X`09incl`09r2 X`09$clref_s efn=r2`09`09`09`09; player 7 X; X`09$clref_s efn=#flag$v_synch+64 X`09$setef_s efn=#flag$v_read+64`09`09; tell everybody to do read X`09rsb X X XSNAKE_READ:: X;+ X;`09BSBW SNAKE_READ X;`09read all users moves and store them into the byte array MOVES(*) X;- X`09bsbw`09ttread`09`09`09`09; read users commands, if any X`09tstb`09r0`09`09`09`09; anything read ? X`09blss`09800$`09`09`09`09; no X500$: X`09movl`09player, r1`09`09`09; get our player number X`09movb`09r0, move(r1)`09`09`09; store our move X`09bneq`09800$`09`09`09`09; if not quit --> 800$ X`09clrl`09score`5Br1`5D`09`09`09; clear score X`09clrl`09n_games`5Br1`5D X`09clrl`09wins`5Br1`5D X`09$exit_s #1`09`09`09`09; and exit program X800$: X`09addl3`09#flag$v_done+64, player, r1 X`09$setef_s efn=r1`09`09`09`09; say that read is complete X900$: X`09blbc`09master, 1000$ X`09$wfland_s efn=#64, mask=other_players`09; wait for all players to read X`09incl`09move_count`09`09`09; onto next move X`09$clref_s efn=#flag$v_read+64`09`09; clear next flag to wait on X`09$setef_s efn=#flag$v_update+64`09`09; tell everybody to update X`09brb`091050$ X1000$: X`09$waitfr_s efn=#flag$v_update+64`09`09; wait for all reads to complete X`09blbs`09master_flag, 1050$`09`09; check for master snake OK X`09movl`09player, r1`09`09`09; get our player number X`09clrb`09move(r1)`09`09`09; store our move ( quit ) X1050$: X`09rsb X X X`09.entry`09- XSNAKE_PLAY, `5Em X;+ X;`09called once at the start of the game. X;`09I then call the Pascal routine ADD_HEAD to perform the moves. X;- X`09blbs`09master, 1000$`09`09; master snake does all the work X100$: X`09bsbw`09snake_wait X`09bsbw`09snake_read X`09$waitfr_s efn=#flag$v_synch+64`09; wait until screen update there X`09bsbw`09snake_update`09`09; update screen X`09brb`09100$ X X900$: X`09clrb`09game_going`09`09; tell other snakes games finished X`09$setef_s efn=#flag$v_synch+64`09; wake other snakes up X`09bsbb`09snake_update`09`09; write out last move X`09ret X X1000$:`09; master snake moves every snake X`09bsbw`09snake_wait X`09bsbw`09snake_read X`09callg`09add_head_par, G`5Eadd_head`09; call Pascal routine X`09`09`09`09`09`09; returns 1 if game still going X`09blbc`09r0, 900$`09`09; game has ended --> 900$ X`09$setef_s efn=#flag$v_synch+64`09; wake other snakes up X`09bsbb`09snake_update`09`09; update our screen X`09brb`091000$ X X X`09.enable local_block X500$: X`09$exit_s #1`09`09`09; game aborted, so exit image X Xsnake_update:: X`09blbs`09abort, 500$ X`09blbs`09dead, 80$`09`09; if we are dead, then no head X;`09replace your snake head with a diamond symbol X`09movc3`09screen_len, screen_buf, outbuf`09; copy update string X`09movl`09player, r2`09`09; get my snake number X`09addw2`09#`5EA/1/+`5EX80, r2`09`09; get number with parity bit set X`09locc`09r2, screen_len, outbuf X`09beql`0950$`09`09`09; could not find it !!! X`09movb`09#`5EA/`60/, (r1)`09`09; change to diamond X50$: X`09callg`09update_par, snake_write X`09blbc`09game_going, 100$`09; bit clear if game has finished X`09bbsc`09player, you_just_died, 60$ ; see if we just died X`09rsb X60$:`09movb`09#1, dead`09`09; say we are dead X`09callg`09text_wait, snake_write`09; tell them to wait for next game_exit, X`09rsb X80$:`09; dont copy buffer if no head to update because we are dead X`09callg`09update_par2, snake_write X`09blbc`09game_going, 100$ X`09rsb X100$: X`09$setimr_s efn=#6, daytim=second_1`09; so we can see last move X`09$waitfr_s efn=#6 X`09ret`09`09`09`09; return from SNAKE_PLAY if end game X`09.disable local_block X X X`09.entry`09- XCHECK_AST, `5Em X;+ X;`09called when check_timer expires (2 seconds) X;`09we should only get here if one of the other snakes has aborted X;`09or `5ES ed . Force the snake out of the game. X;- X`09$readef_s efn=#64, state=cluster_2`09; get done flags X`09extzv`09#flag$v_done, #snake, cluster_2, r2 ; get done flags X;`09movb`09other_players+1, r3`09`09; get other players X`09bicw3`09r2, other_players+1, r3`09`09; find players who have not X`09`09`09`09`09`09; responded X`09bicw2`09r3, other_players+1`09`09; and say they are dead X`09clrl`09r2`09`09`09`09; snake 0 X100$:`09bbc`09r2, r3, 200$ X`09clrb`09move(r2)`09`09`09; say snake has quitted X`09addl3`09#flag$v_done+64, r2, r0`09`09; get event flag X`09$setef_s efn=r0`09`09`09`09; set event flag so I will X`09`09`09`09`09`09; wake up on return from here X200$:`09aoblss`09#snake, r2, 100$`09`09; for all 8 snakes X X`09ret X X X`09.entry`09- XSNAKE_GAME_END, `5Em<> X;+ X;`09synchronizes the end of the game X;- X`09clrb`09dead`09`09`09; we are not dead X`09blbc`09master, 500$`09`09; if not master snake --> 500$ X`09$clref_s efn=#flag$v_game+64`09; say game not in progress X`09clrb`09game_going`09`09; and again X`09$setimr_s efn=#flag$v_endofgame+64, daytim=second_2 X`09clrw`09you_just_died`09`09; reset died flags X500$: X`09$waitfr_s efn=#flag$v_endofgame+64 ; wait for end of game X`09blbs`09abort, 800$`09`09; if we should abort --> 800$ X`09ret X800$:`09; we must abort. Probably because master snake stopped X`09$exit_s #1 X X X`09.entry`09- XSNAKE_EXIT, `5Em X;+ X;`09called as an exit handler X;- X`09$cancel_s chan=mbxchan`09`09; cancel mailbox read X X`09movl`09player, r3`09`09; get my snake number X`09blss`0980$`09`09`09; we never were playing X`09clrb`09move(r3)`09`09; make next move a quit X`09addl3`09#flag$v_done, r3, r2`09; get done bit X`09bbcc`09r2, other_players, 50$`09; stop master snake from waiting for me X50$:`09addl2`09#64, r2`09`09`09; make into event flag X`09$setef_s efn=r2`09`09`09; say input done X`09bbcc`09r3, players, 60$`09; say this snake available X60$: X`09clrl`09score`5Br3`5D`09`09; zero score X`09clrl`09n_games`5Br3`5D`09`09; zero # of games played X80$: X`09blbc`09master, 100$`09`09; are we master snake ? X`09movb`09#1, abort`09`09; tell all other snakes to abort +-+-+-+-+-+-+-+- END OF PART 2 +-+-+-+-+-+-+-+- -+-+-+-+-+-+-+-+ START OF PART 3 -+-+-+-+-+-+-+-+ X`09clrb`09master_flag`09`09; say no master snake X`09$setef_s efn=#flag$v_read+64`09; wake everybody up X`09$setef_s efn=#flag$v_update+64 X`09$setef_s efn=#flag$v_endofgame+64 X`09$setef_s efn=#flag$v_synch+64 X`09$setef_s efn=#flag$v_game+64`09; for people waiting for a game X100$: X;`09clear screen and put out of graphics mode X`09callg`09text_end_game, snake_write X`09blbc`09abort, 200$`09`09; game is not being aborted --> 200$ X`09callg`09text_abort, snake_write X200$: X`09$deltva_s inadr=ret_range`09; delete global section X X;`09$dassgn_s chan=snake_fab+fab$l_stv ; deassign channel X X`09ret X X`09 X`09.entry`09- XNAME_SET, `5Em X;+ X;`09CALL NAME_SET( name ) X;`09set this players name X;- X`09mull3`09#name_size, player, r3`09; get our player number (0-7) X`09addl2`09#13, r3`09`09`09; skip username X`09movc3`09#name_size-13, @4(ap), name(r3) ; store name in shared memory X`09ret X X`09.entry`09- XNAME_GET, `5Em X;+ X;`09CALL NAME_GET( name , player # ) X;`09returns the name of specified player (1-8) X;- X`09subl3`09#1, @8(ap), r1`09`09; get player number (0-7) X`09mull2`09#name_size, r1`09`09; offset to this players name X`09movc3`09#name_size, name(r1), @4(ap) ; return players name X`09ret X X`09.entry`09- XSCORE_SET, `5Em<> X;+ X;`09CALL SCORE_SET( player #, score , # games , # wins ) X;- Xplayer_arg = 4 Xscore_arg = 8 Xgames_arg = 12 Xwins_arg = 16 X`09subl3`09#1, @player_arg(ap), r1`09`09; get our player # (0-snake) X`09movl`09@score_arg(ap), score`5Br1`5D`09; store score X`09movl`09@games_arg(ap), n_games`5Br1`5D X`09movl`09@wins_arg(ap), wins`5Br1`5D X`09ret X X`09.entry`09- XSCORE_GET, `5Em<> X;+ X;`09CALL SCORE_GET( player , score , # games , # wins ) X;- X;player_arg = 4 X;score_arg = 8 X;games_arg = 12 X;wins_arg = 16 X`09subl3`09#1, @player_arg(ap), r1`09`09; get player # (0-snake) X`09movl`09score`5Br1`5D, @score_arg(ap)`09; return score X`09movl`09n_games`5Br1`5D, @games_arg(ap)`09; return # of games played X`09movl`09wins`5Br1`5D, @wins_arg(ap)`09`09; return # of wins X`09ret X X`09.entry`09- Xsnake_game_count, `5Em<> X;+ X;`09CALL SNAKE_GAME_COUNT( # games ) X;`09returns # of games played (total) X;- X`09movl`09game_count, @4(ap) X`09ret X X`09.end $ CALL UNPACK SNAKE.MAR;1 235814742 $ create 'f' X`1B`5BH`1B`5BJ`1B(B`1B`5B0m X`1B`5B1;1H`1B(0lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk lqqqqqqqqqqqqq O`1B V(Bbject `1B(0qqqqqqqqqqqqqk X`1B`5B2;1Hx`1B`5B2;39Hx x`1B`5B2;78Hx`1B`5B3;1Hx lqq lk x lqk k x V lqq x x T`1B(Bo Be The La X`1B`5B3;59Hst Snake Alive `1B(0x`1B`5B4;1Hx x xmk x x mk x lj x V x x`1B`5B4;78Hx X`1B`5B5;1Hx mqqqkx mkx xqqu twj tq x mqqqqqqqqqqqqqqqqqqqqqqq Vqqqqqqqqqqqj X`1B`5B6;1Hx xx xx x x xmk x x lqqqqqqqqqqqqq H`1B(Baza Vrds `1B(0qqqqqqqqqqqqk X`1B`5B7;1Hx lqqqjx mj m x x mk mqqqk x x`1B`5B7;78Hx`1B`5B8;1Hx V x x x x `20 X`1B`5B8;33Hx x x H`1B(Bitting Any Object Will Kill You `1B(0x`1B`5B9;1 VHx`1B`5B9;39Hx x`1B`5B9;78Hx X`1B`5B10;1Hmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj mqqqqqqqqqqqqqqqqqqqqqq Vqqqqqqqqqqqqj X`1B`5B11;1Hlqqqqqqqqqqq I`1B(Bntroduction `1B(0qqqqqqqqqqqqk lqqqqqqqqqqqq V C`1B(Bontrols `1B(0qqqqqqqqqqqqk X`1B`5B12;1Hx`1B`5B12;39Hx x`1B`5B12;78Hx`1B`5B13;1Hx M`1B(Bulti User Game V For Up To 8 Players `1B(0x x`1B`5B13;58H8 `1B(B- X`1B`5B13;61H Up`1B`5B13;78H`1B(0x`1B`5B14;1Hx`1B`5B14;39Hx x`1B`5B14;78Hx` V1B`5B15;1Hmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq X`1B`5B15;39Hj x 4 `1B(B- Left`1B`5B15;66H6 - Right `1B(0x`1B`5B16;1Hl Vqqqqqqqqqqqqq S`1B(Bymbols `1B(0qqqqqqqqqqq X`1B`5B16;35Hqqqqk x`1B`5B16;78Hx`1B`5B17;1Hx`1B`5B17;39Hx x`1B`5B17;58H2 V `1B(B- Down`1B`5B17;78H`1B(0x`1B`5B18;1Hx Y`1B(Bou -`20 X`1B`5B18;11H`1B(0`60 O`1B(Bthers - 1..8 `1B(0x x`1B`5B18;78Hx` V1B`5B19;1Hx`1B`5B19;39Hx x T`1B(Bype "E"`20 X`1B`5B19;60Hto Exit Game `1B(0x`1B`5B20;1Hmqqqqqqqqqqqqqqqqqqqqqqqqqqqq Vqqqqqqqqqj mqqqqqqqqqqqqqqqqqqq X`1B`5B20;63Hqqqqqqqqqqqqqqqj`1B`5B21;1Hlqqqqqqqqqqqq M`1B(Bessages `1B(0qqqq Vqqqqqqqqqqqk lqqqqqqqqqqqqq N`1B(Ba X`1B`5B21;60Hme `1B(0qqqqqqqqqqqqqqqk`1B`5B22;1Hx`1B`5B22;39Hx x `1B(B* V`1B(0`7E `1B`5B22;70H`7E* x X`1B`5B23;1Hmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj mqqqqqqqqqqqqqqqqqqqqqq Vqqqqqqqqqqqqj`1B`5B1;1H X`1B* $ CALL UNPACK SNAKE.SCN;1 185950272 $ create 'f' X`09SUBROUTINE`09HELP_SCREEN XC X`09PARAMETER ESC = 27 X`09CHARACTER Line*256 X BYte REP X`09INTEGER Len_Line,ErrNum XC X`09CALL image_dir() XC X Write(5,111)esc X111 Format(X,A1,'<') X1`09OPEN(UNIT=4,FILE='IMAGE_DIR:SNAKE.SCN',ReadOnly, X`091 STATUS='OLD',IoStat=ErrNum) X If (ERRNUM.EQ.30) Goto 50 X If (ERRNUM.NE.0 ) Goto 999 X100 READ(4,110,END=200) LEN_LINE, LINE(:LEN_LINE) X110 FORMAT(Q,A) X WRITE(5,120) LINE(:LEN_LINE) X120 FORMAT(1X,A) X GOTO 100 X200`09close (unit = 4) X999`09RETURN XC X50`09Write(5,51),Esc,Esc X51 FORMAT(X,A1,'`5B2J',A1,'`5B1;1HPlease wait...') X Call Sleep(4) X Goto 1 XC X END $ CALL UNPACK SNAKEH.FOR;1 1311099332 $ create 'f' X X`7B$S-`7D X`7B$C+`7D X`7B X X XXXXX X X XXXXX X X XXXXXX X X X XX X X X X X X `20 X X X X X X X X X X `20 X XXXXX X X X XXXXXXX XXXX XXXXX`20 X X X X X X X X X X `20 X X X X XX X X X X X `20 X XXXXX X X X X X X XXXXXX X `20 X X`09`09Program`09: Snake X X`09`09Authors`09: Rex Croft - Macro X X Murray Speight - Pascal`20 X X`09`09Place`09: University Of Waikato`20 X X`09`09Date `09: May 1982`20 X X`09Software Is Subject To Change Without Notification X The Author And His Family assume No Rsponsability For X`09Its Reliabliity Or Use.`20 X X `7D X XProgram Snake(Input,Output); X XLabel`099999; `7B For Abortive exit Of Pgm `7D X X XConst `09Max_Num_Players`09= 8; `7B Up To 8 Players `7D X`09Screen_Dim_X `09= 23; `7B PLaying Board 40 * 23 `7D X`09Screen_Dim_Y`09= 40; X`09Len_Of_Buff`09= 1024; `7B Buffer to Write Chars `7D X Max_Name_Length = 32; `7B Lenngth of a players name `7D X XType `09Player_Responce = Packed Array `5B1..Max_Num_Players`5D Of Char; X`09Buffer`09`09= Packed Array `5B1..Len_Of_Buff`5D Of Char;`09 X`09Positions`09= Array `5B1..Max_Num_Players`5D Of INteger; X`09Players_Screen`09= Array `5B1..Screen_Dim_X,1..Screen_Dim_Y`5D Of Char; X`09Died_Type`09= Array `5B1..Max_NUm_Players`5D Of Boolean; X`09Name_Line`09= Packed array `5B1..max_Name_Length`5D of Char; X Name_Table`09= Array `5B1..Max_Num_Players`5D of name_LIne; X XVar `09Responce `09,`09`09`09`7B What Players Have Typed `7D X`09Head_Sym`09: Player_Responce; `7B What Symbol is THe Head `7D X`09Screen`09`09: Players_Screen; `7B 23 * 40 Array For Screen`7D X`09Name`09`09: Name_Table; `7B Names Of Each Player `7D X Init_Pos_X`09, `7B Where initaially Players St Vart `7D X Init_pos_Y , `7B "" "" For Y Coord `7D X`09Score`09`09, `7B Score Of Each PLayer `7D X Game`09`09, `7B Num Games Each PLayer Played ` V7D X`09Games_Won `09, `7B Games Won By Each PLayer `7D X`09Move_X`09`09, `7B What Dir Each Playe Is Moving X C Voord `7D X`09Move_Y`09`09, `7B "" "" Y Coord `7D X`09Head_X`09`09, `7B Where The Head Is For Each Player V X Coord `7D X`09Head_Y`09 `09, `7B "" "" Y Coord `7D X`09Tail_X`09`09, `7B Where The Tail Is For Each Player V X Coord `7D X`09Tail_Y`09`09: Positions; `7B "" "" Y Cord `7D X`09TT_Buff`09`09: Buffer; `7B Lenght Of Buffer To Hold Screen V Output `7D X`09TT_Len`09`09, `7B String To Hold Screen Output `7D X Who_Is_PLaying , `7B Word With Bits Set As To V Who is Playing `7D X`09You`09`09, `7B Which Number You are `7D`20 X`09Dummy `09`09, `7B Dummy argument `7D X`09Num_players , `7B How Many people are Playing ` V7D X`09Max_Player_Number , `7B The Highest PLayers Number wh Vo is Playing `7D X Num_Moved_Last_Round , `7B Number of players who mo Vved last Round ( Last Screen Update ) `7D X`09Players_Removing`09: Integer; `7B Are We Removing Odd 1 or even 2 pl Vayers Tails `7D X`09Quit`09`09, `7B Has The PLayer Quit (not playing ) V or is He Playing `7D X`09Died `09`09: Died_Type; `7B Has The PLayer Died ( Died If He h Vas Quit ) `7D X`09Esc`09`09: Char; `7B esc For escape sequences `7D X`09Seed`09`09: Real; `7B Seed for random number generaotor ` V7D X X XProcedure Break_Buff; X X Procedure Snake_Screen( Var Line : Buffer ; Var Lenght : Integer );extern V;`20 X X`7B Only Call This Once From The Add_head Function`20 X X Does not write array to screen `7D X XBegin X Snake_Screen(TT_Buff,TT_Len);`20 X TT_Len := 0; Xend; X X XProcedure Help_Screen;extern; X XProcedure Pos( X,Y : Integer ; Ch : Char ); X X`7B Write Char at Pos X,Y in Buffer `7D X XBegin X TT_Buff`5BTT_Len+1`5D := Esc; X TT_Buff`5BTT_Len+2`5D := 'Y'; X TT_Buff`5BTT_Len+3`5D := Chr(31+X); X TT_Buff`5BTT_Len+4`5D := Chr(31+Y); X TT_Buff`5BTT_Len+5`5D := Ch; X TT_Len := TT_Len + 5; Xend; X XFunction at(X,Y: Integer):Char; X X`7B Posotion Cursor at X , Y this Is For Use In Write Statments `7D X XBegin X Write(esc,'Y',chr(31+X),Chr(31+Y)); X at := Chr(0); Xend; X X XFunction Snake_Init(Var You : INteger ; Var Game_going : Integer):Integer;e Vxtern; X XProcedure Name_Set(Var Name : Name_Line );extern; X XProcedure Name_Get( VAR Name : Name_Line ; Play : Integer );extern; X XProcedure Score_Set( Player : INTEGER; VAR Score,Games_PLayed,wins : INteger V); X`09`09`09`09`09`09`09extern; XProcedure Score_Get( Player : INTEGER; VAR Score,Games_Played,wins : Integer V ); X`09`09`09`09`09`09`09extern; XProcedure Snake_Start( Var Whos_PLaying : Integer ; var Rand : Positions );E Vxtern; X XProcedure Snake_Read(Var Directions : Player_Responce );Extern; X XProcedure Snake_Game_End;extern; X XProcedure Snake_Wait;Extern; X XProcedure Snake_Game_count( Var Num : Integer);extern; X XProcedure Snake_Dead(Var PLayer : Integer );extern; X XProcedure Sleep( Num_Sec : Integer);extern; X XProcedure Draw_Scores; X XVar I,num_on_table,play,max_score,Top_play,Total_Num_Games,This_score: Integ Ver; X X XBegin X Num_on_Table := 0; X Writeln(esc,'H',Esc,'J',Esc,'G',esc,'<'); X Writeln(' Player User Name Score Game Won Gra Vph'); X writeln(' ------ ---- ---- ----- ---- --- --- V--'); X writeln; X Max_score := -99999; X X `7B Find The Top Player goes By The his Score And Num Of Games Played `7 VD X For PLay := 1 to Max_Num_PLayers do begin X Score_get(Play,Score`5BPLay`5D,Game`5BPLay`5D,Games_won`5Bplay`5D); X If Game`5BPlay`5D > 0 Then Begin X This_score := Round(Score`5Bplay`5D / (Game`5Bplay`5D)**(0.8)); X If This_score > Max_score Then Begin X Top_Play := Play; X Max_score := This_score + 1; X end; X end; X end; X For Play := 1 to Max_Num_PLayers do Begin X If Game`5BPLay`5D > 0 Then Begin `7B IF Games PLayed > 0 Then You A Vre PLaying `7D X Num_On_Table := Num_On_Table + 1; X If PLay = Top_PLay Then`20 X Write(esc,'`5B1m'); `7B High intensity Flash `7D X Write(Play:4); X Write(' ',Name`5BPlay`5D:32); X write(Score`5BPLay`5D:7); `7B Print Info `7D X Write(Game`5BPlay`5D:6); X Write(Games_won`5Bplay`5D:5); X Write(' ',Esc,'`5B7m'); `7B Rev Video `7D X If PLay = Top_PLay Then `20 X Write(' *** Champ *** ') X `09 Else X For I := 1 to Round(Score`5Bplay`5D*15 / ((Game`5Bplay`5D)**(0.8 V)*max_score)) do`20 X Write(' '); X Writeln(esc,'`5B0m'); `7B Normal Video `7D X end; X End; X writeln; X X`7B Print The Games You Have Played With The Totak Num of Games Played so Fa Vr `7D X Snake_Game_Count( Total_Num_games ); X Writeln(' Game # ',Game`5BYou`5D:1,'`09Total # ',Total_Num_Games:1); X writeln; X writeln; X If Num_on_Table <= 1 Then`20 X Goto 9999; X writeln(' Please Wait For Next Game ..... '); X writeln(esc,'`5B?2l',esc,'F'); Xend; X XProcedure Draw_screen; X XVar play,I,X,Y,Line_at : Integer; X X Function Min(A,B:Integer):Integer; X X Begin X If A < B Then`20 X Min := A`20 X Else X Min := B X end; X XBegin `7B Draw Screen `7D X Write(at(1,1),esc,'J',esc,'<',esc,'(0',esc,'<',esc,'(0'); `7B Clear H Vome `7D X Write(esc,'#6l'); X For Y := 1 To (Screen_Dim_Y-2) Do`20 X Write('q'); X Writeln('k'); X For X := 2 To ( Screen_dim_X - 1 ) Do begin X Write(esc,'#6x'); X For Y := 1 to (Screen_Dim_Y-1) do`20 X Write('`7E'); X Writeln('x'); X end; X write(esc,'#6m'); X For Y := 1 to (Screen_Dim_Y-1) Do`20 X Write('q'); X Writeln('j'); X X`7B Show Who You Are At Thje Bottom Of The Screen `7D X Writeln(`7BEsc,'`5B24;1H',Esc,'#6',Esc,'(BYou # ',You:1,`7D X`09 esc,'`5B?2l',esc,'F',at(1,1)); `20 Xend; X X `20 XProcedure initalise_Positions; X X X XVar Mult,Play,X,Y : Integer; X X Rand`09 : Positions; X XBegin X XPlayers_Removing := -1; `7B On First Few Moves Don't remove Tail `7D X XSnake_Start(Who_Is_Playing,Rand); X X X`7B Randomly Position The Starting Pos Of The PLayers `7D XFor play := 1 to Max_num_players do Begin X Head_X`5BPlay`5D := Init_Pos_X`5BRand`5BPlay`5D`5D; X Head_Y`5Bplay`5D := Init_Pos_Y`5BRand`5BPLay`5D`5D; X Move_X`5Bplay`5D := 1; X MOve_Y`5BPlay`5D := 0; Xend; XTail_X := Head_X; XTail_Y := Head_Y; X +-+-+-+-+-+-+-+- END OF PART 3 +-+-+-+-+-+-+-+- -+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+ XMult := 2**7; `7B 2 ** Number of PLayers - 1`7D XNum_Players := 0; X X`7B Examine Each Bit In Mult To See If You Are Playing `7D XMax_player_number := 0; XFor Play := Max_Num_PLayers downto 1 do begin X If ( Who_Is_PLaying div Mult ) = 1 Then begin X Name_Get(Name`5BPlay`5D,Play); X Num_Players := Num_PLayers + 1; X Quit`5Bplay`5D := False; `7B Bit Set You Are Playing `7D X Who_is_Playing := Who_is_Playing - Mult; X If Max_player_number = 0 Then`20 X Max_player_number := play ;`7B The Highest Numbered Player `7D X end else begin X Quit`5BPlay`5D := True; `7B Bit Not Set Not Playing ie Quit `7D X end; X Mult := Mult div 2; Xend; X XNum_Moved_Last_Round := 0; X X`7B If You are PLaying Then You Havnt Died `7D XFor Play := 1 to Max_Num_Players Do Begin X If Not Quit`5BPlay`5D Then Begin X Died`5BPlay`5D := False; X Num_Moved_Last_Round := Num_Moved_Last_Round + 1; X end else X Died`5Bplay`5D := True; X responce`5BPlay`5D := ' '; `7B Initalise First Responce Should Not BE N Veeded `7D Xend; XFor PLay := 1 to Max_Num_PLayers do`20 X Game`5BPLay`5D := Game`5BPLay`5D + 1; XFor X := 1 To Screen_Dim_X do`20 X For Y := 1 to Screen_Dim_Y do X Screen`5BX,y`5D := '`7E'; XFor Y := 1 To Screen_Dim_Y do Begin X Screen`5B1,Y`5D := 'q'; X Screen`5BScreen_Dim_X,Y`5D := 'q'; Xend; XFor X := 1 To Screen_Dim_X Do Begin X Screen`5BX,1`5D := 'x'; X Screen`5BX,Screen_Dim_Y`5D := 'x';`20 Xend; XScreen`5B1,1`5D := 'l'; XScreen`5B1,Screen_Dim_Y`5D := 'k'; XScreen`5BScreen_Dim_X,1`5D := 'm'; XScreen`5BScreen_Dim_X,Screen_Dim_y`5D := 'j'; XHead_Sym`5B1`5D := chr(128+ord('1')); `7B Set The Bits In The Chars `7D XHead_Sym`5B2`5D := chr(128+ord('2')); XHead_Sym`5B3`5D := chr(128+ord('3')); XHead_Sym`5B4`5D := chr(128+ord('4')); XHead_Sym`5B5`5D := chr(128+ord('5')); XHead_Sym`5B6`5D := chr(128+ord('6')); XHead_Sym`5B7`5D := chr(128+ord('7')); XHead_Sym`5B8`5D := chr(128+ord('8')); X XFor Play := 1 to Max_Num_PLayers do`20 X If Not Quit`5Bplay`5D Then`20 X Screen`5BHead_X`5BPlay`5D,Head_Y`5BPlay`5D`5D := 'O'; X`7B Note If This Procedure Is Only Called When You Are Master Snake`20 X Draw Screen Should Be In The Mainlkine Before Init_pos X And The Writing Of The PLayers Pos Should Be To The Buffer`20 X And Then Written To All Who Are PLaying `7D X XDraw_screen; `20 X X`7B Pos Inital Player Positions `7D XFor Play := 1 to Max_Num_PLayers do `20 X If ( Not Quit`5BPlay`5D ) Then `20 X Writeln(at(Head_X`5BPlay`5D,Head_Y`5BPlay`5D),Head_sym`5BPlay`5D); Xend; X XProcedure Initalise_Mainline; X XVar Zero,Init_Rep,PLay,Name_pos,Game_Going : Integer; X XProcedure Verify_name(VAr Name : Name_Line ); X XVar I : INteger; X X XBegin X For I := 1 to Max_Name_length do `7B Remove All Invalid Chars From The V Name`7D X If ( Name`5Bi`5D < ' ' ) or ( Name`5Bi`5D > '`7E' ) Then Begin X Write(chr(7)); X Name`5Bi`5D := ' '; X end; Xend; X X XBegin X Esc := Chr(27); X Seed := Clock; X TT_Len := 0; X `20 X X `7B set where Each Player Starts `7D X X Init_pos_X`5B1`5D := 2; X Init_pos_Y`5B1`5D := 2; X `20 X Init_pos_X`5B2`5D := Screen_dim_x - 1; X Init_pos_Y`5B2`5D := Screen_dim_Y - 1; X `20 X Init_pos_X`5B3`5D := 2; X Init_pos_Y`5B3`5D := Screen_dim_y - 1; X `20 X Init_pos_X`5B4`5D := Screen_dim_x - 1; X Init_pos_Y`5B4`5D := 2; X `20 X Init_pos_X`5B5`5D := 2; X Init_pos_Y`5B5`5D := Screen_dim_Y div 2; X `20 X Init_pos_X`5B6`5D := Screen_dim_x - 1 ; X Init_pos_Y`5B6`5D := Screen_dim_Y div 2; X `20 X Init_pos_X`5B7`5D := Screen_dim_x div 2; X Init_pos_Y`5B7`5D := 2; X `20 X Init_pos_X`5B8`5D := Screen_dim_x div 2; X Init_pos_Y`5B8`5D := Screen_dim_Y - 1; X X Writeln(Esc,'<'); `7B Vt52 Mode `7D X Writeln(Esc,'`5B1;1H',Esc,'`5BJ'); `7B Clear Screen `7D X Init_rep := Snake_Init(You,Game_going); X You := You + 1; `20 X If Init_rep = 1 Then Begin X `7B you are the First Person to play zero all the scores `7D X For Play := 1 to Max_Num_PLayers do begin X Zero := 0; X Score_Set(Play,Zero,zero,zero); X end; X Help_Screen; X Writeln(esc,'`5B1;1H',Esc,'`5B?2l'); X Writeln(at(22,3),' Please Enter Your Name Player #',You:1); X Write(at(22,51)); X Readln(Name`5BYou`5D); X Verify_Name(Name`5BYou`5D); X Name_set(Name`5BYou`5D); X Write(at(22,3), ' Hit < Return > When Others Ready '); X Readln; X Writeln; X Write(at(22,3), ' Please Wait For Game To Start '); X Writeln; X end Else Begin X If You = 0 Then Begin X Writeln(esc,'`5B1;18H',Esc,'#3SNAKE'); X Writeln(esc,'`5B2;18H',Esc,'#4SNAKE'); X Writeln(esc,'`5B4;8H' ,Esc,'#6Sorry No Snakes Available'); X`09 Sleep(3); X goto 9999; X end else begin `7B Init_rep = 0 `7D`20 X Help_Screen; X Writeln(esc,'`5B1;1H',Esc,'`5B?2l'); X Writeln(at(22,3),' Please Enter Your Name Player # ',You:1); X Write(at(22,51)); X Readln(Name`5BYou`5D); X Verify_name(Name`5BYou`5D); X Name_set(Name`5BYou`5D); X Writeln; X Write(at(22,3), ' Please Wait For Game To Start '); X Writeln; X If Game_Going = 1 Then`20 X Snake_Game_End; X end; X end; X Game`5BYou`5D := 0; Xend `7B Initalise Mainline `7D; X XFunction Correct_Sym(Last_Move_X,Last_Move_Y,Move_X,Move_Y:Integer):Char; X XBegin `7B Calculates The Correct symbol To Write Given The Dir You Were In V `7D X Case (Last_Move_X+1) + (Last_Move_Y+1)*4 Of`20 X 6 : `7B Down `7D X Case (Move_X+1) + (Move_Y+1)*4 Of`20 X 6 : `7B Down `7D X Correct_Sym := 'x'; X 9 : `7B Right `7D X Correct_Sym := 'm'; X 1 : `7B Left `7D X Correct_Sym := 'j'; X 4 : `7B Up Note : This Is Poss On First Move `7D X Correct_Sym := 'x'; X end `7B Case `7D; X 4 : `7B Up `7D X Case (Move_X+1) + (Move_Y+1)*4 Of`20 X 6 : `7B Down `7D X Correct_Sym := 'x'; X 4 : `7B Up `7D X Correct_Sym := 'x'; `20 X 9 : `7B Right `7D X Correct_Sym := 'l'; X 1 : `7B Left `7D X Correct_Sym := 'k'; `20 X end `7B Case `7D; X `20 X 9 : `7B Right `7D X Case (Move_X+1) + (Move_Y+1)*4 Of`20 X 6 : `7B Down `7D X Correct_Sym := 'k'; `20 X 4 : `7B Up `7D X Correct_Sym := 'j'; `20 X 9 : `7B Right `7D X Correct_Sym := 'q'; X 1 : `7B Left `7D X Correct_Sym := 'q'; `20 X end `7B Case `7D; X X 1 : `7B Left `7D X Case (Move_X+1) + (Move_Y+1)*4 Of`20 X 9 : `7B Right `7D X Correct_Sym := 'q'; X 6 : `7B Down `7D X Correct_Sym := 'l'; `20 X 4 : `7B Up `7D X Correct_Sym := 'm'; `20 X 1 : `7B Left `7D X Correct_Sym := 'q'; `20 X end `7B Case `7D; X X end `7B Case `7D; Xend; `7B Correct Sym `7D X X`5BGLOBAL`5D Function Add_head( Var Responce : Player_responce ):Integer; X XVar Play, Num_Moved, Dir_X, Dir_Y, Pos_x, Pos_Y : Integer; X X X XProcedure Remove_tail( Var STail_X , STail_Y : Integer ); X XVar Last_X,Last_Y : Integer; X XBegin `7B removes the Tail of the snake whose tail is at StailX,Y `7D X`7B The Character To Move is determined by the Char at the tail X and if a character joins up to it `7D X X Last_X := STail_X; X Last_Y := STail_Y; X Pos(STail_X,STail_Y,'`7E'); X Case Screen`5BSTail_X,STail_Y`5D of`20 X 'l' : If Screen`5BStail_X,STail_Y+1`5D In `5B'k','j','q'`5D Then`20 X STail_Y := STail_Y + 1 X Else X STail_X := STail_X + 1; X 'k' : If Screen `5BSTail_X,STail_Y-1`5D In `5B'l','m','q'`5D Then`2 V0 X STail_Y := STail_Y - 1 X Else X Stail_X := STail_X + 1 ; X 'm' : If Screen`5BSTail_X,STail_Y+1`5D In `5B'k','j','q'`5D Then X Stail_Y := STail_Y + 1 X Else X Stail_X := Stail_X - 1 ; X 'j' : If Screen`5BSTail_X,STail_Y-1`5D In `5B'm','l','q'`5D Then`20 X STail_Y := STail_Y - 1 X Else X STail_X := STail_X - 1; X 'x' : If Screen`5BSTail_X-1,STail_Y`5D In `5B'l','k','x'`5D Then`20 X STail_X := STail_X - 1 X Else X STail_X := STail_X + 1; X 'q' : If Screen`5BSTail_X,STail_Y - 1 `5D In `5B 'l','m','q'`5D The Vn`20 X STail_Y := STail_Y - 1 X Else X STail_Y := STail_Y + 1; X end `7B CAse `7D; X Screen`5BLast_X,Last_Y`5D := '`7E'; Xend `7B remove_Tail`7D; X X XProcedure Remove_Players_tail( play : Integer ); X XVar X,Y : Integer; X XBegin `7B Removed Odd Players Tails Of Play = 1 Even If 2 `7D X While Play <= Max_PLayer_Number do Begin X If Not Died`5BPlay`5D Then `20 X Remove_tail(Tail_X`5BPLay`5D,Tail_Y`5BPLay`5D); X Play := Play + 2; X end; Xend; X X XProcedure Add_This_Players_Head; X Xbegin X If Not Quit`5BPlay`5D And (Ord(Responce`5BPLay`5D) = 0 ) Then begin X Died`5BPLay`5D := True; `7B If PLayer quit Then`20 X Quit`5BPLay`5D := True; Initalise all Variables `7D X Game`5BPlay`5D := 0; X Score`5BPlay`5D := 0; X Games_Won`5BPLay`5D := 0; X Score_Set(Play,Score`5BPlay`5D,Game`5BPLay`5D,Games_Won`5BPLay`5D); X end else`20 X If Not Died`5BPlay`5D Then Begin X Dir_X := Move_X`5BPlay`5D; X Dir_Y := Move_Y`5BPLay`5D; X`09 Pos_X := Head_X`5BPlay`5D; X Pos_Y := Head_Y`5BPlay`5D; X `7B Change Direction Of The Position You Move To is Not A Wall ie = V '.' `7D X Case Ord(responce`5BPlay`5D) Of`20 X 8 : If Screen`5BPos_x-1,Pos_Y`5D = '`7E' Then Begin X Dir_X := -1 ; X Dir_Y := 0 ; `7B Moving Up `7D X end; X 2 : If Screen`5BPos_X+1,Pos_Y`5D = '`7E' Then Begin X Dir_X := 1; X Dir_Y := 0; `7B Moving Down `7D X end; X 4 : If Screen`5BPos_X,Pos_Y-1`5D = '`7E' Then Begin X Dir_X := 0; `7B Moving Left `7D X Dir_Y := -1; X end; X 6 : If Screen`5BPos_X,Pos_Y+1`5D = '`7E' Then Begin X Dir_X := 0; `7B Moving Right `7D X Dir_Y := 1; X end; X otherwise `7B Do Nothing Same Dir As Before `7D X end `7B Case `7D; X `7B Given LAst Direction Or New Direction `7D X If Screen`5BPos_X + Dir_X , Pos_Y + Dir_Y `5D = '`7E' Then Begin `2 V0 X`09 `7B Going into a Blank square ok to move `7D X Num_Moved := Num_Moved + 1; X Screen`5BPos_X ,Pos_Y `5D :=`20 X Correct_sym(Move_X`5BPlay`5D,Move_Y`5BPLay`5D,Dir_X,Dir_Y) V; X pos(Pos_X,Pos_Y,Screen`5BPos_X,Pos_Y`5D); X Pos_X := Pos_X + Dir_X; X Pos_Y := Pos_Y + Dir_Y; X Screen`5BPos_X,Pos_Y`5D := 'O'; X Pos(Pos_X,Pos_Y,Head_Sym`5BPLay`5D); X end else begin `7B You HAve Died Hit Into A Non Blank Square `7D X Died`5BPlay`5D := True; X If Num_PLayers <> Num_Moved_Last_Round Then `20 X Score`5BPlay`5D := Score`5BPlay`5D +`20 X (( Num_PLayers - Num_Moved_Last_Round + 1 )**2 * 100 ) V`20 X div ( NUm_Players**2); X pos(Pos_X,Pos_Y,Correct_sym(Move_X`5BPlay`5D,Move_Y`5BPLay`5D,Di Vr_X,Dir_Y)); X Pos_X := Pos_X + Dir_X; X Pos_Y := Pos_Y + Dir_Y; X`09 Snake_Dead(play);`20 X end; X Move_X`5BPlay`5D := Dir_X; X Move_Y`5BPLay`5D := Dir_Y; X`09 Head_X`5BPlay`5D := pos_X; X Head_Y`5BPlay`5D := Pos_Y; X end; Xend; X Xbegin X Num_Moved := 0; `7B Iniotalise Counter For The Number Who Move Vd `7D X If Players_reMoving = 1 Then Begin `7B If 1 Then Loop Clockwise `7D X For Play := 1 to Max_Player_number do`20 X add_This_Players_head; X Remove_players_tail(1); `7B Remove Odd Players Tail `7D X PLayers_ReMoving := 2; `7B Next Round Shall remove Even V Ones `7D X end else`20 X If Players_removing = 2 Then Begin X For Play := Max_Player_Number downto 1 do`20 X add_This_Players_head; `7B Go Clockwise In Updatin Vg `7D X Remove_Players_tail(2); X PLayers_ReMoving := 1; X end else begin X For Play := Max_Player_Number downto 1 do `7B First Few Moves Don't V remove Tail `7D X add_This_Players_head; `7B Go Clockwise In Updatin Vg `7D X Players_removing := Players_removing + 1; X end; X If Num_Moved <= 1 Then Begin `7B Ie There IS Only 1 or 0 V PLayers Left `7D X For PLay := 1 to Max_player_Number do Begin X`09If Not Quit`5BPlay`5D Then Begin X If Not Died`5BPLay`5D Then Begin X Score`5BPLay`5D := Score`5BPlay`5D + 100; `7B One Hundred V If You Last Left `7D X Games_Won`5BPLay`5D := Games_Won`5BPLay`5D + 1; X end; X Score_set(Play,Score`5BPlay`5D,Game`5BPlay`5D,Games_Won`5BPLay`5 VD); X end; X end; X Add_head := 0; `7B Return 0 To Stop The Game `7D X end else`20 X Add_Head := 1; `7B 1 To Comtinue `7D X Num_Moved_Last_Round := Num_Moved; X Break_Buff; `7B does not write the buffer just says To`20 X Write this buffer to all the players when add_head exits V `7D Xend `7B add_Head`7D; X X XProcedure Snake_PLay;extern; X X XBegin `7B Mainline `7D X LineLimit(Output,MaxInt); X Initalise_Mainline; X While True Do Begin +-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+- -+-+-+-+-+-+-+-+ START OF PART 5 -+-+-+-+-+-+-+-+ X Initalise_Positions; `7B initalises pos Only relavent for master V snake `7D X Snake_Play; `7B Calls Add_head with the Moves of the pla Vyers until add_head returns 1 ( end of game ) `7D X Draw_Scores; X Snake_Game_End; `7B Syncs all players Together `7D X end; X9999 :`20 X Writeln(esc,'<'); Xend. $ CALL UNPACK SNAKEP.PAS;1 141985560 $ v=f$verify(v) $ EXIT -------------------------------------------------------------------------------- (04/07/93) - WWB The LIBRARY subdirectory has been updated to reflect Rex Croft's update to the UTIL object library. Games SNAKE and TANK have been updated accordingly. --------------------------------------------------------------------------------