-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgame.tex
96 lines (88 loc) · 2.81 KB
/
game.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
\newcount\score \newcount\xx \newcount\yy \newtoks\cells
\def\currcell{\csname board/\the\xx:\the\yy \endcsname}
\def\setcurrcell#{\expandafter\expandafter\expandafter\edef\currcell}
\def\doboard{%
\xx\z@ \yy\z@
\loop
\xx\z@{\loop
\expandafter\expandafter\expandafter\do \currcell
\advance\xx\@ne \ifnum\xx<\boardsize\repeat}%
\advance\yy\@ne
\ifnum\yy<\boardsize\repeat
}
\def\boardsend#1{%
\if h#1
\let\next\boardml
\else\if j#1
\let\next\boardmd
\else\if k#1
\let\next\boardmu
\else\if l#1
\let\next\boardmr
\else\if s\expandafter\@car#1\@nil
\edef\next{\noexpand\boardset \expandafter\@cdr#1\@nil ,\noexpand\@nil,\noexpand\displayboard}%
\else \boardunknown
\fi\fi\fi\fi\fi \next
}
\def\boardunknown{\techo{\ttcolorb{red}Unrecognized input: \expandafter\@car\in\@nil \treset}}
\def\boardset#1,{\ifx\@nil#1\relax\else \expandafter\boardsetA\romannumeral-`0#1\@nil \expandafter\boardset \fi}
\def\boardsetA#1 #2 #3\@nil{\csgdef{board/#1:#2}{#3}}
\def\boardm#1#2#3{%
\cells{}%
\qloop#2\boardsize{%
\tmptokA{}%
{%
#3#1\boardsize{%
\tmptokA\expanded{{\the\tmptokA {\currcell}}}% stage cells in tl
}%
\squish % the actual work
\wrcell#3#1% % write back result
}%
}\randins \displayboard
}
\def\boardml{\boardm\xx\yy\qloop}
\def\boardmd{\boardm\yy\xx\rloop}
\def\boardmu{\boardm\yy\xx\qloop}
\def\boardmr{\boardm\xx\yy\rloop}
\newtoks\out
\def\merge#1{\out{}\mergeA0#1\relax}
\def\mergeA#1#2{%
\ifx\relax#2\toksapp\out{{#1}}\else
\ifx0#2\def\next{\mergeA{#1}}\else
\ifnum#1=#2\edef\next{\noexpand\mergeA{\the\numexpr\@ne+#1}}\global\advance\score\getcellval{\numexpr1+#1}\else
\ifnum#1=\z@\else \toksapp\out{{#1}}\fi \def\next{\mergeA{#2}}\fi\fi
\expandafter\next
\fi
}
\def\squish{\out\tmptokA \squishA}
\def\squishA{%
\edef\tmpa{\the\out}%
\expandafter\merge\expandafter{\the\out}%
\edef\tmpb{\the\out}%
\ifx\tmpa\tmpb
\tmpcntA \expandafter\len\expandafter{\the\out}%
\edef\tmpa{\the\out\replicate{\boardsize-\tmpcntA}{{0}}}% pad with empty cells
\else \expandafter\squishA \fi % apply until no change between iterations
}
\def\wrcell#1#2{%
#1#2\boardsize{%
\global\setcurrcell{\expandafter\@car\tmpa\@nil}%
\edef\tmpa{\expandafter\@gobble\tmpa}%
}%
}
\def\randins{%
\tmpcntA\z@
\let\do\randinsA \doboard
\tmpcntA\pdfuniformdeviate\tmpcntA \tmpcntB\z@
\let\do\randinsB \doboard
}
\def\randinsA#1{\ifnum#1=\z@ \global\advance\tmpcntA\@ne \fi}
\def\randinsB#1{\ifnum#1=\z@ \ifnum\tmpcntA=\tmpcntB \xdef#1{\the\numexpr\@ne+\pdfuniformdeviate\tw@}\fi \global\advance\tmpcntB\@ne \fi}
\def\boardinit{%
\score\z@
\chardef\boardsize=\if\relax\in\relax 4\else \in\fi
\def\do##1{\gdef##1{0}}\doboard
\randins
\tposul \displayboard \readin
}
\def\init{\afterassignment\boardinit \read\m@ne to\in}