NB. TTT3D game - 2D code NB. DanB 2000/03/03 NB. Last mod 2000/10/01 VERSION=: 2j25 NB. This is an add-on to the original TTT code. It must be loaded AFTER it. NB. NOTE: a lot of code was cannibalized from an APL version NB. require 'ttt3d' NB. core code require 'isigraph' NB. where the the gl... verbs are NB. 2 verbs are of interest here: gdlines and gdpolygon. NB. The first allows to draw the cube, the second the tokens. NB. * These are the form's callback fns ========================== wd=: 11!:0 NB. Window driver - should already be there cubeform_cube_char =: 1&SpinCube cubeform_cube_mmove=: 0: cubeform_cube_mblup=: PlaceUp cubeform_cube_mbrdown=: 0: NB. WINPOPUP not available in this version cubeform_cube_mbldown=: PlaceDown cubeform_Istart_button=: Istart cubeform_Ustart_button=: Ustart cubeform_L0_button=: Level@0: cubeform_L1_button=: Level@1: cubeform_L2_button=: Level@2: cubeform_L3_button=: Level@3: cubeform_ch_button=: Challenge cubeform_credits_button=: 3 : 0 NB. milinta 19990717 show the name of the person who did this wdinfo 'Tic Tac Toe 3D ver ',(":VERSION),' by Dan Baronet.',CR,'Original in 1978, APL/PC version in 1989, this version 2000' ) cubeform_huh_button=: 3 : 0 WIN_VIEWTEXT 'General help'; DESCRIBE ) cubeform_technique_button=: 3 : 0 NB. milinta 19991110 display technique used WIN_VIEWTEXT 'TTT3D Technique used'; TECHNIQUE ) Level=: 3 : 0 if. CanChangeLevel do. Force=: y.{0 1 4 25 end. for_i. i.4 do. wd 'set L',(":i),' ',":CanChangeLevel*y.=i end. ) NB. * End of callback fns =========================== Challenge=: 3 : 0 NB. milinta 19990806 challenge user if. WIN_ASK 'Challenge!';'This will start a new game where I will play my best.',LF,'Do you wish to continue ?' do. Istart 98 ChangeLevel 0 Level 0 NB. this will remove tik marks in menu end. ) cursor=: 3 : 0 NB. milinta 20000127 set shape of cursor i.0 0 NB. until available ) draw=: 3 : 0 NB. assumes canvas for drawing cube already exists glsel 'cube' NB. object to be affected glclear '' NB. clear previous picture glmapraw '' NB. respecify characteristics glmap MM_TEXT drawcube X SLOTS O glshow '' NB. show result ) drawcube=: 3 : 0 NB. SHOWCUBE SLOTS;PLANES;PLINES NB. milinta 19991108 show new cube layout and slots NB. This sets globals 'PORDER'. 'CENTERS', 'PLINES' and 'PLANES'. NB. The SLOTS' positions are in CENTERS. Drawing order of planes is in PORDER. AxisTilt setcubevars 1.5 NB. Right arg is the planes' spacing factor NB. Display the cube plane by plane, the furthest (last) one first L=. Green; Blue; Red; Purple [ 'sls col'=. |: y. sls=.>sls NB. regroup slots for_P. PORDER do. glrgb P PICK L NB. the plane's color glpen 2 0 NB. select 2 pixels wide, solid (0) gllines, P{PLANES NB. the plane's contour glpen 1 0 NB. select 1 pixel wide, solid (0) gllines,. P{PLINES NB. the lines in the plane NB. on each plane there are 0 or more tokens of various colors if. +./s=.sls onplane P do. NB. any token? NB. we do each color one by one for_c. =cp=.s#col do. glrgb {.c#cp NB. its color glbrush '' glpolygon ,.(c#s#sls){CENTERS NB. draw the token glrgb Black NB. draw a black line around the token glpen 1 0 glpolygon ,.(c#s#sls){CENTERS end. end. end. ) newform =: 3 : 0 wd newformWD draw X=:O=:'' wd 'pshow' ) NB. Create "ttt3d" form that can be closed with the X Windows button. NB. Coords are centered extending about 200 in each direction. newformWD=: 0 : 0 pc cubeform closeok;pn "Tic Tac Toe 3D"; rem * All menus here; menupop "New Game"; menu Istart "I start" "" "Computer starts a new game" ""; menu Ustart "You start" "" "YOU start a new game" ""; menupopz menupop "Options"; menupop "Level"; menu L0 "0" "" "computer plays at random" "easiest"; menu L1 "1" "" "computer plays at random but blocks you" "easy"; menu L2 "2" "" "computer is smarter" "tough"; menu L3 "3" "" "pretty hard to beat if you don't start" "deadly"; menupopz menu ch "Challenge" "" "Nobody's ever beaten me here!" "Unbeatable mode"; menupopz; menupop "Help"; menu credits "About TTT3D" "" "Who did this" ""; menu technique "Technique" "" "How it's done" ""; menu huh "What IS this?" "" "Full description" "Detailed help"; menupopz; rem * Status bar; sbar 1 ; sbarset status 100 "Click on an unused slot"; sbarshow; rem * The image object (a drawing surface); xywh 0 0 200 200;cc cube isigraph ws_clipchildren ws_clipsiblings rightmove bottommove; pas 0 0;pcenter; rem * Form end; ) NB. R=.S ONPLANE PL NB. Slots are in the range 0..63, PLanes in 0..3 onplane=: ] = [ <.@% 16"_ NB. R=.DIST ONTOXY C NB. PROJECT C onto XY plane from DISTance NB. C is 3 col str: X, Y {&} Z coords ontoXY=: ( }:@] * [ % [ - {:@])"1 setcubevars=: 4 : 0 NB. at SETCUBEVARS ps;T;#IO NB. Prepare globals. 4 vars define the 4 planes' positions, NB. their inner lines (6 on each plane) and the 64 slots' centers. NB. All must be modified for the tilting on each axis and the NB. corrective spacing between planes. NB. Finally a last transformation is applied to account for the NB. projection on the screen (with perspective) and in the window. F=. * 2: {"1 ] NB. Fn to modify last coordinate ps=. y. F PLANES0 T=.ps (0 ) CR=: 10{a. DESCRIBE=: 0 : 0 3-D X and Os (Tic-Tac-Toe) The game is played in a cube 4*4*4 and we play one after the other aiming at filling in 4 slots in a row, pretty much like in the traditional 3*3 game. The cube is shown as four planes each of a different color, each with 4*4 positions. To play, simply specify the position chosen by clicking with the mouse on the slot where you want to play. IF YOU CAN'T REACH THE SLOT YOU WANT, ROTATE THE CUBE WITH THE ARROW KEYS OR BY DRAGGING THE MOUSE. To win you must line up 4 slots with your color. I, the program, am your opponent. My strength may be specified in the menu. By default I play at "Block" level, meaning that I will block your attempts at lining up 4 slots but I won't use any strategy to win. At the "Easiest" level I play randomly and I won't try to block you. At higher levels I try to foresee a winning situation. The higher the level, the better I am. In "challenge" mode I start at the highest level. You don't stand many chances. If I am about to win I will announce my move and how many moves you have left. It will look like "I play C12..." where C is the plane's color (Green, Blue, Red or Purple) and 12 means "first (closest) row, 2nd leftmost slot" Here's an example. I use 4 planes side by side but on the screen they will be stacked up of course: G B R P 4> . . . . . . . . . . . . . . . . 3> . . . . . . . . . . . . . . . . 2> . . . . . . . . . . x . . . . . 1> . o . . . . . . . . . . . . . . ^ ^ ^ ^ 1 2 3 4 Here, the 'x' is at position R23 and the 'o' at G12. Examples of winning sequences (using 4 different colors A, B, C & D): 1: A11 A12 A13 A14 Note that winning slots are 2: D14 D23 D32 D41 always either on the same plane or 3: A31 B31 C31 D31 on a different plane for each slot. 4: A41 B42 C43 D44 The same rule applies to columns 5: A44 B33 C22 D11 and rows...! A B C D 4> 4 . . 5 . 4 . . . . 4 . 2 . . 4 3> 3 . . . 3 . 5 . 3 . . . 3 2 . . 2> . . . . . . . . . 5 . . . . 2 . 1> 1 1 1 1 . . . . . . . . 5 . . 2 ^ ^ ^ ^ 1 2 3 4 You play with the orange slots and I with the blue ones. Use the arrow keys to rotate the cube or drag the mouse to rotate the cube and get a better view. When one of us wins I show the winning slots in RED. Good luck. Dan Baronet. ) Force=:2 LineMode=: 0 MaxTilt=: 0 0 40 MinTilt=: _90 0 _40 MDown=: 0 ObsDist=: 24 PlaceDown=: 3 : 'MDown=: 2{. 0".sysdata' NB. Note where the mouse went down PlaceUp=: 3 : 0 NB. Place msg;pos;range;hit;lv;s;#IO;spot;over;diffxy;moved NB. milinta 19991110 place token on screen NB. The mouse has just been clicked UP NB. We use coordinates from the top left corner. The mouse uses the BOTTOM left corner. NB. We need to adjust the mouse's position according to the height (3{sysdata) of the form. pos=.--/2 2$0,1 0 3{xy=. 0 ".sysdata NB. is mouse click position over 15 pixels radius? if. 15<|j./diffxy=.-MDown-2$xy do. NB. yes, spin the cube 0 SpinCube diffxy else. NB. no, must be a selection then over=.-.+./STATE e. 0 1 2 3 10 20 30 NB. any playable slot? over=.over+.+./iu=.40 4 e. STATE NB. did user hit something? iu=. ' won. ',~,>iu#'I';'You' NB. proceed by plane, the closer 1st: for_s. ,(|.PORDER){i.4 4 4 do. spot=. s{CENTERS NB. find where lies the square if. pos within spot do. NB. if the mouse is within range... if. over do. NB. of course, if the game is over WIN_MSG msg=.'Game over.' NB. simply display the appropriate msg wd 'set status *',iu,msg else. NB. otherwise if. SHOWn do. WIN_MSG 'hit=',":s,pos,spot end. if. s{FREESLOTS do. NB. if the slot is free FREESLOTS=: FREESLOTS *. ALL~:s O=:O,s [ STATE=:STATE + +./"1 Lines=s NB. add to list Moves_s_=:Moves_s_,@{ PLANES0=: 4 5 3 $ 4 4 3 4 _4 3 _4 _4 3 _4 4 3 4 4 3 4 4 1 4 _4 1 _4 _4 1 _4 4 1 4 4 1 4 4 _1 4 _4 _1 _4 _4 _1 _4 4 _1 4 4 _1 4 4 _3 4 _4 _3 _4 _4 _3 _4 4 _3 4 4 _3 PLINES0=: 4 6 2 3 $ _2 4 3 _2 _4 3 0 4 3 0 _4 3 2 4 3 2 _4 3 4 _2 3 _4 _2 3 4 0 3 _4 0 3 4 2 3 _4 2 3 _2 4 1 _2 _4 1 0 4 1 0 _4 1 2 4 1 2 _4 1 4 _2 1 _4 _2 1 4 0 1 _4 0 1 4 2 1 _4 2 1 _2 4 _1 _2 _4 _1 0 4 _1 0 _4 _1 2 4 _1 2 _4 _1 4 _2 _1 _4 _2 _1 4 0 _1 _4 0 _1 4 2 _1 _4 2 _1 _2 4 _3 _2 _4 _3 0 4 _3 0 _4 _3 2 4 _3 2 _4 _3 4 _2 _3 _4 _2 _3 4 0 _3 _4 0 _3 4 2 _3 _4 2 _3 RotateAngle=: 8 ROT=: 4 : 0 NB. R=.AXIS ROT S NB. rotate S about all 3 axes R=.y. for_i. 2 1 0 do. R=.(i,~i{x.) ROTA R end. NB. R=.(AXIS[1],1)ROTA(AXIS[2],2)ROTA(AXIS[3],3)ROTA S ) ROTindices=: 3 3 3 $ 1 0 0 0 2 3 0 4 5 2 0 3 0 1 0 4 0 5 2 3 0 4 5 0 0 0 1 ROTA=: 4 : 0 NB. R=.AA ROTA M;A;AX;B NB. Rotate on Axis. AA is Axis Angle in deg and Axis (0=x,1=y,2=z). 2=$ NB. M is Xd struct. 'A axis'=. x. [ M=.y. NB. Is it worth doing? (angle<>0?) if. 0~:A do. i=. axis{ROTindices NB. a 3x3 R=.1 2 o. TORAD A factors=. i{0 1,(1 _1 * |. R),R M=.M +/ . * factors end. M ) SpinCube=: 4 : 0 NB. SpinCube msg;key;shift;mag;orig NB. milinta 19991107 rotate cube orig=.AxisTilt NB. let's see if we'll move if. x. do. NB. a keyboard move key=.a. i. {.sysdata mag=.RotateAngle NB. magnitude of the change NB. 'key' is one of the arrow keys. AxisTilt=:AxisTilt + mag * --/2 3$166 0 165 168 0 167=key else. mag=. _1|. 0, y.%10 _10 AxisTilt=:AxisTilt + mag end. AxisTilt=:MaxTilt<.MinTilt>.AxisTilt if. -.orig-:AxisTilt do. draw '' end. ) SLOTS=: 4 : 0 NB. R=.X SLOTS O 'X O'=.x.;y. col=.(,#&>X;O)#Xcolor;Ocolor [ xo=.X,O if. -.WinLine-:0 do. col=.(