init
la-ninpre leobrekalini@gmail.com
Mon, 04 Jul 2022 16:05:16 +0300
5 files changed,
390 insertions(+),
0 deletions(-)
A
LICENCE
@@ -0,0 +1,15 @@
+ISC License + +Copyright (c) 2022 la-ninpre + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE.
A
Makefile
@@ -0,0 +1,23 @@
+SRC = tictactoe.tal + +OBJ = $(SRC:.tal=.rom) + +CLEANFILES = $(OBJ) + +UXNASM = uxncli ~/roms/drifblim.rom + +all: $(OBJ) + +.tal.rom: + $(UXNASM) $< + +$(OBJ): $(SRC) + +run: $(OBJ) + uxnemu -s 3 $< + +clean: + rm -f $(CLEANFILES) + +.PHONY: all run clean +.SUFFIXES: .tal .rom
A
README.md
@@ -0,0 +1,25 @@
+# tictactoe.tal + +simple little game that took me far longer than i thought it would. + +## installation + +there is a makefile for convenience (you need uxncli, uxnemu and drifblim.rom). +but you can just assemble `tictactoe.tal` in any way you want. + +this command: + +``` +$ make run +``` + +will assemble the game using drifblim.rom and will run it in uxnemu. + +## controls + +**arrow keys** to move, **button A** (or control or space) to make your move. +when the game is over, press any button to restart. + +## licence + +ISC (see `LICENCE`).
A
tictactoe.tal
@@ -0,0 +1,326 @@
+( tic tac toe ) + +( devices: {{{ ) +|00 @System + [ &vector $2 + &wst $1 + &rst $5 + &r $2 + &g $2 + &b $2 + &debug $1 + &state $1 + ] +|20 @Screen + [ &vector $2 + &width $2 + &height $2 + &auto $2 + &x $2 + &y $2 + &addr $2 + &pixel $1 + &sprite $1 + ] +|80 @Controller + [ &vector $2 + &button $1 + &key $1 + ] +( }}} ) + +|0000 +@game + [ &cursor-pos $1 ( high nibble - x, low nibble - y ) + ¤t-player $1 ( 01 - x, 02 - o ) + &moves $1 ( 00 - 09 ) + &cells $9 ( 00 - empty, 01 - x, 02 - o ) + ] + +|0100 ( -> ) + ( add .theme support ? ) + #1c2f .System/r DEO2 + #1b3a .System/g DEO2 + #1c3a .System/b DEO2 + + #0050 .Screen/width DEO2 + #0050 .Screen/height DEO2 + + ;on-controller .Controller/vector DEO2 + + ;init-game JSR2 + + ( border ) + #0010 #000f #30 #02 #01 ;draw-line-at JSR2 + #000f #0010 #30 #02 #02 ;draw-line-at JSR2 + #0010 #0040 #30 #02 #01 ;draw-line-at JSR2 + #0040 #0010 #30 #02 #02 ;draw-line-at JSR2 + + ( cells ) + #0010 #001f #30 #02 #01 ;draw-line-at JSR2 + #0010 #002f #30 #02 #01 ;draw-line-at JSR2 + #0010 #003f #30 #02 #01 ;draw-line-at JSR2 + #001f #0010 #30 #02 #02 ;draw-line-at JSR2 + #002f #0010 #30 #02 #02 ;draw-line-at JSR2 + #003f #0010 #30 #02 #02 ;draw-line-at JSR2 +BRK + +@init-game ( -- ) + #11 .game/cursor-pos STZ + #01 .game/current-player STZ + #00 .game/moves STZ + + ( clear the board ) + #09 &while + DUP #01 SUB .game/cells ADD #00 SWP STZ + #01 SUB DUP ,&while JCN + POP + + .game/cursor-pos LDZ #01 ;draw-cursor-at JSR2 +JMP2r + +@on-controller ( -> ) + .game/cursor-pos LDZ + + .Controller/button DEI + #01 ANDk NIP ,&play JCN + #10 ANDk NIP ,&up JCN + #20 ANDk NIP ,&down JCN + #40 ANDk NIP ,&left JCN + #80 ANDk NIP ,&right JCN + POP + .Controller/key DEI + #20 EQUk NIP ,&play JCN + POP2 BRK + + &play + POP + DUP ;pos-to-addr JSR2 LDZk + #00 EQU ,&draw JCN + POP2 BRK + &draw + .game/current-player LDZ + SWP STZ + ;draw-move-at JSR2 + .game/moves LDZk INC SWP STZk + ( game can't be ended before 5 moves ) + POP #05 LTH ,&no-check JCN + ;check-win JSR2 + &no-check + BRK + &up + POP + DUP #00 ;draw-cursor-at JSR2 + ;move-cursor/up JSR2 + #01 ;draw-cursor-at JSR2 + BRK + &down + POP + DUP #00 ;draw-cursor-at JSR2 + ;move-cursor/down JSR2 + #01 ;draw-cursor-at JSR2 + BRK + &left + POP + DUP #00 ;draw-cursor-at JSR2 + ;move-cursor/left JSR2 + #01 ;draw-cursor-at JSR2 + BRK + &right + POP + DUP #00 ;draw-cursor-at JSR2 + ;move-cursor/right JSR2 + #01 ;draw-cursor-at JSR2 +BRK + +@on-controller-trap ( -> ) + .Controller/button DEI ,&restart JCN + .Controller/key DEI ,&restart JCN + BRK + &restart + #0100 JMP2 +BRK + +@check-win ( -- ) + ( diagonals ) + #00 ;pos-to-addr JSR2 LDZ + #11 ;pos-to-addr JSR2 LDZ + #22 ;pos-to-addr JSR2 LDZ AND AND + #02 ;pos-to-addr JSR2 LDZ + #11 ;pos-to-addr JSR2 LDZ + #20 ;pos-to-addr JSR2 LDZ AND AND + ORA + + ( columns ) + #03 &while-x1 + #03 &while-y1 + DUP2 #01 DUP SUB2 + SWP #40 SFT ORA + ;pos-to-addr JSR2 LDZ STH + #01 SUB DUP ,&while-y1 JCN + POP + STH2r STHr AND AND STH + #01 SUB DUP ,&while-x1 JCN + POP + STH2r STHr ORA ORA + ORA + + ( rows ) + #03 &while-y2 + #03 &while-x2 + DUP2 #01 DUP SUB2 + #40 SFT ORA + ;pos-to-addr JSR2 LDZ STH + #01 SUB DUP ,&while-x2 JCN + POP + STH2r STHr AND AND STH + #01 SUB DUP ,&while-y2 JCN + POP + STH2r STHr ORA ORA + ORA + DUP ,&endgame JCN + .game/moves LDZ #09 EQU ,&endgame JCN + POP + JMP2r + &endgame + ;draw-endgame JSR2 + ;on-controller-trap .Controller/vector DEO2 +JMP2r + +@move-cursor ( pos -- newpos ) + &up + #03 ANDk NIP + #00 EQUk NIP #03 MUL ADD + #01 SUB SWP #30 AND ORA + ,&end JMP + &down + #03 ANDk NIP + #02 EQUk NIP #03 MUL SUB + INC SWP #30 AND ORA + ,&end JMP + &left + #04 SFTk NIP + #03 AND + #00 EQUk NIP #03 MUL ADD + #01 SUB #40 SFT + SWP #03 AND ORA + ,&end JMP + &right + #04 SFTk NIP + #03 AND + #02 EQUk NIP #03 MUL SUB + INC #40 SFT + SWP #03 AND ORA + &end + .game/cursor-pos STZk POP ( lil side effect : ) +JMP2r + +@draw-cursor-at ( pos col -- ) + STH + ;pos-to-xy JSR2 + OVR2 OVR2 + .Screen/y DEO2 + .Screen/x DEO2 + #0e STHrk #01 ;draw-line JSR2 + #0e STHrk #02 ;draw-line JSR2 + .Screen/y DEO2 + .Screen/x DEO2 + #0e STHrk #02 ;draw-line JSR2 + #0f STHr #01 ;draw-line JSR2 +JMP2r + +@draw-move-at ( pos -- ) + ;pos-to-xy JSR2 + #0003 ADD2 + .Screen/y DEO2 + #0003 ADD2 + .Screen/x DEO2 + .game/current-player LDZ + ;draw-figure JSR2 +JMP2r + +@draw-figure ( fig -- ) + #00 EQUk NIP ,&tie JCN + #01 EQUk NIP ,&x JCN + #02 EQUk NIP ,&o JCN + POP JMP2r ( this should never happen (tm) ) + + &tie + POP + .Screen/x DEI2k #0008 SUB2 ROT DEO2 ( align ) + #01 .Screen/auto DEO + ;tie DUP2 .Screen/addr DEO2 + #01 .Screen/sprite DEO + #0008 ADD2k NIP2 .Screen/addr DEO2 + #01 .Screen/sprite DEO + .Screen/addr DEO2 + #11 .Screen/sprite DEO + #00 .Screen/auto DEO + JMP2r + &x + POP + ;x .Screen/addr DEO2 + #01 .Screen/sprite DEO + #02 .game/current-player STZ ( evil stuff ) + JMP2r + &o + POP + ;o .Screen/addr DEO2 + #03 .Screen/sprite DEO + #01 .game/current-player STZ ( very evil ) + JMP2r +JMP2r + +@draw-endgame ( winstate -- ) + #13 ;pos-to-xy JSR2 + #0003 ADD2 + .Screen/y DEO2 + #0003 ADD2 + .Screen/x DEO2 + ;draw-figure JSR2 +JMP2r + +@draw-line ( wid col dir -- ) + .Screen/auto DEO + SWP + &while + SWP .Screen/pixel DEOk POP + SWP #01 SUB DUP ,&while JCN + POP2 + #00 .Screen/auto DEO +JMP2r + +@draw-line-at ( x* y* wid col dir -- ) + STH2 STH + .Screen/y DEO2 + .Screen/x DEO2 + STHr STH2r ;draw-line JSR2 +JMP2r + +@pos-to-xy ( pos -- x* y* ) + #04 SFTk NIP + #03 AND + #01 ADD #00 SWP #0010 MUL2 + ROT + #03 AND + #01 ADD #00 SWP #0010 MUL2 +JMP2r + +@pos-to-addr ( pos -- addr ) + #04 SFTk NIP + #03 AND + #03 MUL + SWP + #03 AND + ADD + .game/cells ADD +JMP2r + +( data ) + +@x c3e7 7e3c 3c7e e7c3 +@o 7ee7 c3c3 c3c3 e77e +@tie 0000 e010 1008 0807 + 0824 1410 0146 3800 + +( vim: fdm=marker: )