This repository has been archived by the owner on Dec 30, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
HACKING
188 lines (143 loc) · 7.13 KB
/
HACKING
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
This file is intended as a brief overview for those who are interested in
hacking Anonymine, and as a maintenance manual for me.
Versions 0.1.15 and above are in my Github repo:
git clone https://github.com/oskar-skog/anonymine.git
Older versions are only available from my downloads archive:
https://oskog97.com/archive/anonymine/
Files in this package
=====================
Asterisk marks that the file will be created during building.
Those files exist in $(builddir) while all other files are in $(srcdir).
ChangeLog --
FAQ --
INSTALL Installation instructions for *nix
INSTALL.Haiku "Installation" instructions for Haiku
* Makefile (Generated by ./configure)
Makefile.static The source file for Makefile
* Makefile.vars For remaking Makefile; (Generated by ./configure)
NEWS --
README (It's an order! :)
RELEASE-NOTES Does this version bite?
* anonymine (Generated by make)
anonymine.py The curses interface for game (interface/engine)
anonymine_engine.py The engine part of the game (interface/engine)
anonymine_fields.py Defines the minefields
anonymine_solver.py Solving algorithm
* check.py Self-tests to prevent embarrassing releases
check.sh Used internally by check.sh
configure See "INSTALL"
configure.py Used internally by configure
cursescfg The configuration file for the curses interface
desktop/ Non-essential files for the graphical environments:
FILES List of files.
README Overview of the contents of the desktop directory.
enginecfg.fallback Used if enginecfg.out can't be autogenerated.
* enginecfg.out The configuration file for the game's engine
? enginecfg.user Create this yourself if you want to
install-cfg Script for installing configuration files
mkdist make dist; (the file explains why it exists)
mkenginecfg Create enginecfg.out
* mkenginecfg.py Used internally by mkenginecfg
* reconfigure For remaking Makefile; (Generated by ./configure)
test.py Misc small unnecessary functions: demos, etc
? enginecfg.user is a file that you can create manually if you want to.
enginecfg.user MUST be created in $(builddir), not $(srcdir).
Game construction
=================
anonymine.py
|
+--anonymine_engine.py
| |
| +--anonymine_solver.py
| |
| +--anonymine_fields.py
| |
| \--enginecfg
|
\--cursescfg
Game engine ("anonymine_engine.py")
-----------------------------------
The interface is an object with certain methods and is passed as
an argument to `engine_instance.play_game`.
Engine instances are created by giving the game parameters to the
`game_engine` class. Because of this, this module is only capable
of moore/hex/neumann. (This module also imports the fields module.)
It requires the enginecfg configuration file.
See the doc string for `anonymine_engine.game_engine` for details.
The module also contains the `hiscores` class of which an instance
is returned as the second return value of `anonymine_engine.play_game`.
Instances of `hiscores` have methods for displaying the highscores
and adding the new entry.
The add new entry method takes an input function as an argument.
See the doc string for `anonymine_engine.hiscores` for details.
Game interface and fields module ("anonymine.py", "anonymine_fields.py")
------------------------------------------------------------------------
The fields module contains two classes for squares and hexagons.
The squares' class's __init__ method takes a `moore` keyword
parameter to differ between Moore and von Neumann neighbourhoods.
The generic_field class makes the square fields, and can handle any
positive integer amount of dimensions. (Only 2D is used by the game.)
I have not yet properly documented all the needed methods of field
classes, but if you do implement another one, make sure it has all
of the public methods generic_field has.
The interface module/main executable contains
- A curses interface class for creating the interface object to
send to `anonymine_engine.game_engine.play_game`.
The interface module requires the "cursescfg" configuration file.
- An argument handling function. (Requires argparse, no-op without.)
- A human input function, parser function, and a quite useful `ask`
function.
- A main function without fault handling (leave curses).
(Fault handling is in the __name__ == '__main__' conditional.)
- A `play_game` function.
- A function for retrieving nickname and a function for displaying
highscores with the help of less(1).
- EINTR handling on IO due to a Python+curses bug.
Field solver ("anonymine_solver.py", related: "anonymine_fields.py")
--------------------------------------------------------------------
You are not expected to understand this module.
It looks too complicated for doing something as simple as solving
minesweepers, so there are probably some solvable fields that it can't
solve. The other way around, however, should not be the case.
It is completely unaware of the "physical" representation of the fields.
It sees them as abstract networks rather than arrays, and can work with
pretty much anything.
Configuration files
-------------------
cursescfg: Go ahead and hack it.
enginecfg: This is trickier, because this file is usually autogenerated
by "mkenginecfg". "enginecfg.fallback" is used if "enginecfg.out" can't
be autogenerated. You can also override the autogenerated and fallback
versions by creating "enginecfg.user".
Installation procedure
======================
configure
|
\--configure.py
*
*<--Makefile.static
*
*-->Makefile
|
+--check.sh
| *
| *-->check.py
|
\--mkenginecfg->mkenginecfg.py
*
*-->enginecfg.out
Installed enginecfg / enginecfg.out priority:
1: enginecfg.user - manually created before installation
2: mkenginecfg.py output - if it works
3: enginecfg.fallback - fallback if mkenginecfg.py fails
Version number is set ONLY in "Makefile.static".
Most of the installation stuff happens in Makefile.static.
NOTE 1:
"make uninstall" MUST remove files that may have been installed by
an older version of Anonymine. (Due to update procedure.)
configure.py
------------
Automatically (or manually by command line arguments) set Makefile
variables in a newly created Makefile and append Makefile.static.
It should be quite reusable. Just remove unnecessary finder functions
and add necessary ones.