Commit cac8c841 authored by Oskar Skog's avatar Oskar Skog

Initial commit (contains version 0.1.15)

parents
__pycache__
*.tar.gz
*.zip
*.pyc
*~
ignore
Makefile
anonymine
anonymine.desktop
icon.icns
Info.plist
check.py
anonymine-wrapper
BUG#0 2016-01-03
NO HYPOTHESIS
Version: Anonymine 0.0.15
Python: CPython 3.1.3
OS: (DEAD) Debian Squeeze (kFreeBSD 8)
curses.version: 2.2
Library: ncurses5.7
Description:
Things get fucked up when curses gets reinitialized.
Symptoms:
(1st game works fine)
2nd game: Crap is written on the terminal.
Requires complete redrawing.
Issues with aborting the game. Stuck in an infinite loop.
A new game starts immediately; no questions are asked while
not in curses mode.
Sending a ^Z during the first or second game and then bringing the
game back to foreground seems to disarm the issue with aborting.
NOTICE:
This VM "died" of some reason.
I can't do any further testing.
BUG#1 long known, insignificant
Python: CPython 2.7.3 (3.2.3 doesn't seem to have this bug,
but further testing is needed.)
OS: Only one has been tested: Trisquel 6.0 (Linux 3.2)
curses.version: 2.2
Library: ncurses5.9
Description
If the screen has been resized while in curses mode,
the interpreter may write some warning when exiting:
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
BUG#2 2016-01-07, solved
Solved in 0.0.25, bug is available in 0.0.24 and below:
A bug in anonymine_solver.py (solver.rule9bf) has been fixed,
the symptoms of this bug haven't occured since the fix.
(At least 717708 fields (30x16 with 99 mines) have been tested.)
Traceback:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/cProfile.py", line 29, in run
prof = prof.run(statement)
File "/usr/lib/python2.7/cProfile.py", line 135, in run
return self.runctx(cmd, dict, dict)
File "/usr/lib/python2.7/cProfile.py", line 140, in runctx
exec cmd in globals, locals
File "<string>", line 1, in <module>
File "test.py", line 39, in run_prof
won, levels = solver.solve()
File "anonymine_solver.py", line 1105, in solve
success, update_difficulty = self.solver_loop()
File "anonymine_solver.py", line 957, in solver_loop
unsolved_cells.append((cell, rank_cell([cell], i)))
File "anonymine_solver.py", line 934, in rank_cell
more_cells = cells + self.number_neighbours(cells)
File "anonymine_solver.py", line 638, in number_neighbours
assert self.field.get(neighbour) != 'X'
AssertionError
(SOLVED) BUG#3 2016-01-08, severe
More or less platform specific.
OS: Debian 8 (Linux 3.16) (x86-64)
Python: CPython 2.7.9, CPython 3.4.2
curses.version: 2.2
Library: ncurses5.9
Description:
After forking, it appears, when the field is being initialized, the
curses mode stops working.
Solution:
Define a program mode and temporarily reset to shell mode while
initializing the field.
The cursor can still not be hidden, so it will be moved to an
unimportant place.
The screen requires one complete redrawal of the screen, so that
will also be done.
NOTICE:
DO NOT REMOVE.
This is referenced from the source.
BUG#4 is bogus
BUG#5
The user's own configuration files have a higher priority than the system
wide, and will be loaded if available. If they are out of date the game
will crash.
BUG#6 2016-02-03
There was a small possibility that another slave would finish before
getting killed by the master, causing os.kill to fail.
Because of this, the slaves will from now on be killed with SIGCONT
rather than SIGTERM, as SIGCONT will be ignored by an innocent process
that might start after a second slave finishes but before the slave
gets killed by the master.
BUG#7 2016-02-09
anonymine.py (curses_game.output)
window.bkgdset causes a nasty issue when the background character
is not space (0x20).
Workaround in place.
Problematic platforms
=====================
#0 Debian GNU/kFreeBSD (Debian Squeeze)
#1 Debian 7 with CPython 2.6.7
#2 openindiana
#3 PyPy
#4 Cygwin
#0:
OS: Debian Squeeze (6.x)
kernel: kFreeBSD k8
arch: x86-32 (VirtualBox)
Python: CPython 3.1.3
curses.version: 2.2
curses library: ncurses 5.7
severity: Potentially severe.
symptoms: First round is symptom-free. The game can be quit
after the first game. The following rounds:
^C doesn't work; ^Z doesn't work; crap is printed on
the screen whenever you do something; doesn't ask for
the game parameters between the rounds.
#1
OS: Debian 7
kernel: Linux
arch: x86-32 (VirtualBox)
Python: CPython 2.6.8
curses.version 2.2
curses library: ncurses 5.9
severity: minor/potentially medium
symptoms: Terminal resizing doesn't work.
#2
OS: openindiana
kernel: illumos
arch: x86-32 (VirtualBox)
Python: CPython 2.6.4
curses.version: 2.2
curses library: unknown
terminal: GNOME Terminal 2.30.2
severity: bad
symptoms: * Manual installation required:
Incompatible install(1M)
* Crashes the terminal window on the second game.
* Crashes ALL terminal windows when the window is
shrunk too much.
#3
OS: Debian 8 (Also with Trisquel 6.0 )
kernel: Linux 3.16 ( with Linux 3.2)
arch: x86-64 (native)
Python: PyPy (2.4.0) (language: 2.7.8)
curses: irrelevant
severity: severe
symptoms: The solver function misbehaves.
This probably causes the long/infinite initialization
times.
Traceback (archived version 0.0.29):
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "test.py", line 258, in runneumann
print(solver.solve())
File "anonymine_solver.py", line 1115, in solve
success, update_difficulty = self.solver_loop()
File "anonymine_solver.py", line 978, in solver_loop
status = self.cell_solver(cell, 4*i + j)
File "anonymine_solver.py", line 842, in cell_solver
""".format(possibilities)
AssertionError:
Cell already solved?? []
#4
OS: Cygwin (unknown)
Windows: NT 6.0 (64 bit) or NT 6.1 (64 bit)
arch: x86-64
Python: 2.7.10 (python package on Cygwin; probably CPython)
curses: unknown
severity: conditionally severe
symptoms: Screen goes black on resizing.
This diff is collapsed.
How does the algorithm work with the different games?
The solver operates on a network of cells connected to all of their
neighbours. It has no clue of the visual representation.
Can it play a real game for the user?
No, but yes in theory. There might be a few demo functions in 'test.py'.
(Notice: They are not curses based!)
How can the game always be possible to win?
It contains an algorithm that will try to solve the game before you see
the field. If the field can't be solved, a new will be randomized, and
if it can be solved, the algorithm will tell the game where to place the
mines.
Can I change the colors?
Yes, the configuration file /etc/anonymine/cursescfg defines the key
bindings and colors. If the in-file documentation is not sufficient,
you can ask me a follow up to the question.
On Windows, the file is "C:\Cygwin\etc\anonymine\cursescfg",
assuming you installed as administrator.
Is Cygwin required for the Windows version?
Actually no, but it's convenient:
- Most of the installation procedure use the pre-existing
./configure && make && make install
- Without fork(2), it will take a few times longer to initialize
a minefield.
- Without Cygwin, Python would require a separate curses module.
It should work on Python for Windows with a manually installed curses
module.
BUGS Known bugs, may also include descriptions of old bugs
ChangeLog --
FAQ --
FILES This file
INSTALL Installation instructions
* Makefile (Generated by ./configure)
Makefile.static The source file for Makefile
NEWS --
README (It's an order! :)
Windows-admin.bat Installation script for Windows (auto-fetch Cygwin)
Windows-user.bat Installation script for Windows (auto-fetch Cygwin)
Windows.txt Installation instructions for Windows
* 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 Self-tests to prevent embarrassing releases
configure See "INSTALL"
configure.py Used internally by configure
cursescfg The configuration file for the curses interface
enginecfg The configuration file for the game's engine
install-cfg Script for installing configuration files
test.py Misc small unnecessary functions: demos, etc
desktop/ Non-essential files for the graphical environments:
FILES List of files.
README Overview of the contents of the desktop directory.
perkele/ Abandoned stuff
Asterisk marks that the file will be created during building.
0.1.0
Properly documented source.
0.2.0
Performance improvements, no nasty calibration of enginecfg.
0.3.0
High-scores.
0.4.0
Maybe mouse support.
0.5.0 (or 0.4.0)
Create a statistics collection module.
0.6.0 (or 0.5.0)
Good documentation for the solver algorithm.
WINDOWS USERS
=============
Read "Windows.txt" instead.
DEPENDENCIES
============
* Python >= 2.6 (3.x allowed)
* The curses module. (Python bindings for curses.)
* A screen size of at least 10 columns by 8 rows.
(7 by 4 for non-hexagonal gametypes.)
* A unix-like operating system AND/OR the argparse module.
Normal installation will only work on unix-like operating
systems.
On unix-unlike systems you must specify the location of both
configuration files, which is why the argparse module would
be required on a non-nix platform.
PROPER INSTALLATION
===================
Some progress has been made; the Makefile will be written by the configure
script.
If you want to use srcdir and builddir, you still have to configure the
Makefile manually.
In the directory extracted from the tarball, run:
./configure
make
make install # as root
NOTICE:
The system-wide configuration files for the game will only be created if
they do not exist. `make install` will fail if the format of the
configuration has changed and old configuration files exist.
To force an overwrite of the system-wide configuration files, run
`make overwrite-cfg`. If you do this because of a failed make install,
run make install again.
Anonymine will be installed as 'anonymine'.
You may want to make some changes to '/etc/anonymine/enginecfg'.
RUN IN CURRENT DIRECTORY
========================
You can run Anonymine right here in this directory (the directory) of the
package.
python anonymine.py -c cursescfg -e enginecfg
ADVANCED INSTALLATION
=====================
Important notes
===============
* Anonymine expects to be run by "python", not "python2.7" etc; Make
sure you have those symlinks.
* The other version of python is expected to by "python3" or
"python2"; make sure you have that symlink as well if you want the
modules to be installed for both versions.
* You may want to make some changes to '/etc/anonymine/enginecfg'
after installation.
./configure; make; make install
===============================
./configure will accept variables with three different syntaxes:
./configure --name value
./configure --name=value
./configure name=value
All variables/options require exactly one value/argument.
All variables will also be stored in the Makefile.
The value of a variable MAY be a Makefile variable/macro.
The value entered on the command line will not be pre-expanded in the
Makefile, except for "builddir" and "srcdir". The exception is there
to prevent issues when make is run from a different directory than
configure.
"srcdir" and "builddir" will automatically be converted to absolute
paths.
configure will also accept these short options:
-f Force; write the Makefile even if there were errors.
-v verbose
-w Use sys.prefix as prefix. (For quickly removing old
versions.)
The real "configure" script will handle these:
./configure -h
./configure -V
./configure --help
./configure --version
Recognised variables
====================
Variable default and/or description
-------- --------------------------
prefix sys.prefix
bindir $(prefix)/bin NOTICE: may not work as expected.
gamesdir $(prefix)/games
libdir $(prefix)/lib
EXECUTABLES This program will be installed in $(gamesdir)
MODULES See its own subsection
MODULES_OTHERVER See its own subsection
DESTDIR Pretend the root is here
srcdir The directory extracted from the tarball.
builddir (Current working directory)
freedesktop Empty=false, non-empty=true; "Linux" desktop
macosx Empty=false, non-empty=true; Mac OS X
windows Empty=false, non-empty=true; Windows (Cygwin)
prefix, bindir and libdir:
http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
DESTDIR
https://www.gnu.org/prep/standards/html_node/DESTDIR.html
srcdir and builddir
-------------------
$(srcdir) is the directory that was extracted from the tarball.
$(builddir) is the directory where make(1) is allowed to create
"temporary" files when building (`make [all]`) the program.
Both of these default to the current working directory.
EXECUTABLES
===========
This is the directory to which this game will be installed.
It will be assigned to the first variable of [gamesdir, bindir]
that expands into a path that exists in $PATH.
As a consequence: The game will probably not be installed where
you want it to if you specify bindir=somewhere-else as it installs
to gamesdir rather than bindir (if possible).
MODULES and MODULES_OTHERVER
============================
As Python 3 is slightly backwards-incompatible with Python 2,
both version may be installed.
This game works with both versions of Python, and installs three
modules that could be used by some other program.
The modules will be copied to $(MODULES). And if there is another
Python, symlinks to the installed modules will be created in
$(MODULES_OTHERVER).
The default value of MODULES and MODULES_OTHERVER is the first
of the following that exists in sys.path:
$(libdir)/python$(major)/site-packages
$(libdir)/python$(major).$(minor)/site-packages
$(libdir)/python$(major)/dist-packages
$(libdir)/python$(major).$(minor)/dist-packages
$(major) and $(minor) are pre-expanded and do NOT exist in the
Makefile.
Targets in the Makefile
=======================
all (default)
Fix the shebang line of the programs to be installed
clean
Remove stage files and bytecode.
print-destinations
Print where things will be installed.
install
Configuration files will not be replaced by this target.
Installation will fails if the pre-existing configuration files
are incompatible with the new version of the software, and the
old version should be left untouched.
overwrite-cfg
Overwrite the configuration files.
NOTICE: This does not ask for confirmation.
uninstall
This will remove the system-wide configuration files as well.
To remove an installed version older than 0.0.31 you'll need
to run ./configure with the -w option.
check
Check that everything seems to work.
tarballs
make tarballs
zip
Generate an archive suitable for Windrugs users.
- zip
- CRLF line endings
- .txt
release
(You are me.)
make dist
'check' that I am not making an embarrassing release,
make 'tarballs' and the 'zip' and 'release' them.
Copyright (c) Oskar Skog, 2016
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
This software is provided by the copyright holders and contributors "as is"
and any express or implied warranties, including, but not limited to, the
implied warranties of merchantability and fitness for a particular purpose
are disclaimed. In no event shall the copyright holder or contributors be
liable for any direct, indirect, incidental, special, exemplary, or
consequential damages (including, but not limited to, procurement of
substitute goods or services; loss of use, data, or profits; or business
interruption) however caused and on any theory of liability, whether in
contract, strict liability, or tort (including negligence or otherwise)
arising in any way out of the use of this software, even if advised of the
possibility of such damage.
This diff is collapsed.
What's new in 0.1.0 since 0.0.0?
================================
- The documentation should now be complete.
- The solver is now ten times as fast and the initializer more efficient.
- Various resizing bugs (crashes) have been fixed.
- The installation method has matured.
- Various changes to the textics.
- The statistics methods in anonymine_solver have been deprecated.
- Portability:
0.0.1: FreeBSD (`make dist` works since 0.0.21)
0.0.8: Python 3
0.0.15: Python 2.6
0.0.27: BUG#3 is fixed (at least Debian Jessie x86-64 was affected)
0.0.31: Minix 3 and openindiana (illumos (OpenSolaris))
0.0.36: NetBSD works properly
0.0.41+: Windows (auto-fetch Cygwin) (lack of testing)
- **Backwards-incompatible changes**:
"anonymine.py", and files that will not be installed, are not included!
0.0.19: "initcfg" was renamed to "enginecfg"
0.0.19: `anonymine_engine.game_engine.__init__` will now take the
path to the configuration file as a positional argument.
0.0.36: 'doc-moore' and 'doc-neumann' was merged into 'doc-square' in
"cursescfg".
- Misc
0.0.9: Separated game engine from interface.
0.0.11: Don't mess up the terminal on error.
0.0.35: It is now possible to move diagonally in the von Neumann mode.
0.0.36: Removed the old initializer from the engine and 'wait' from
enginecfg.
0.0.37: Added the 'T' level of difficulty for the time it took.
Broken releases:
Python 2 broke on 0.0.38
Python 3 broke on 0.0.33
Anonymine is a curses mode minesweeper that checks if the fields actually are
solvable without guessing and has a few other features.
The game doesn't have a real name yet; suggestions are welcome.
Apart from being solvable without guessing, anonymine:
* can use traditional Moore neighbourhoods (8 neighbours per cell),
* a hexagonal field (6 neighbours per cell)
* or von Neumann neighbourhoods (4 neighbours per cell).
* The anonymine_solver module can also be used to "measure the difficulty"
of a field.
See also
========
* Windows.txt for installation instructions for Windows.
* INSTALL for installation instructions. ./configure; make; make install
* FILES to get a hint of all files in the package.
Untested platforms
==================
* Cygwin (Tested, unknown version)
* Mac OS X
* CPython on native Windrugs; Is there a "curses" module and does it work?
Tested platforms
================
This is a list of platforms on which Anonymine works.
Note that Python 2.6, 3.0 and 3.1 are not expected to have the
module "argparse".
CPython 2.6.6 is lowest tested.
platform Notes
-------- -----
Cygwin ? on NT 6.1 [Py 2] Crash on resize, ver 0.1.0
Debian6/kFreeBSD8 [Py 2] No more testing can be done
Debian 7
Debian 8 [Py 2, 3] BUG #3
FreeBSD 9.2 [Py 2]
Mac OS X [Py 2] Can't use PNG for icons, ver 0.1.6
Minix 3.3 [Py 2] $(prefix) is /usr/pkg
NetBSD 6.1 [Py 2] No color
OpenBSD 5.8
OpenSUSE 12.2 [Py 2, 3]
Trisquel 6.0 [Py 2, 3]
openindiana GNOME terminal is buggy.
GOALS
=====
0.1.0
Properly documented source.
0.2.0
Performance improvements, no nasty calibration of enginecfg.
0.3.0
High-scores.
0.4.0
Maybe mouse support.
0.5.0 (or 0.4.0)
Create a statistics collection module.
0.6.0 (or 0.5.0)
Good documentation for the solver algorithm.
Copyright
=========
Copyright (c) Oskar Skog, 2016
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
This software is provided by the copyright holders and contributors "as is"
and any express or implied warranties, including, but not limited to, the
implied warranties of merchantability and fitness for a particular purpose
are disclaimed. In no event shall the copyright holder or contributors be
liable for any direct, indirect, incidental, special, exemplary, or
consequential damages (including, but not limited to, procurement of
substitute goods or services; loss of use, data, or profits; or business
interruption) however caused and on any theory of liability, whether in
contract, strict liability, or tort (including negligence or otherwise)
arising in any way out of the use of this software, even if advised of the
possibility of such damage.
:: @echo off
:: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Where you want Cygwin to be installed:
set cygwin_dir=C:\Cygwin
:: Where you want the Cygwin installer to be placed, (including filename):
set cygwin_setup=%cygwin_dir%\setup.exe
:: Temporary, make sure this doesn't exist.
set dlroot=C:\Tmp-anonymine
:: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: URLs and valid destination file names.
set src64=https://cygwin.com/setup-x86_64.exe
set src32=https://cygwin.com/setup-x86.exe
set dl64=%dlroot%\setup-x86_64.exe
set dl32=%dlroot%\setup-x86.exe
:: 64/32
if exist %systemroot%\SysWOW64\ set src=%src64%
if exist %systemroot%\SysWOW64\ set dl_setup=%dl64%
if not exist %systemroot%\SysWOW64\ set src=%src32%
if not exist %systemroot%\SysWOW64\ set dl_setup=%dl32%
:: http://stackoverflow.com/questions/9681863/windows-batch-variables-wont-set
:: Can't have these in the conditional that checks whether Cygwin exists or not.
:: Procedures:
:: 1. Install Cygwin if needed.
:: 2. Install the dependencies of the game.
:: 3. Start a Cygwin environment.
:: 4. Install the game.
:: Information:
:: https://cygwin.com/cgi-bin2/package-grep.cgi
:: http://ss64.com/nt/syntax.html
:: http://ss64.com/nt/bitsadmin.html
:: BITS is so retarded that the source file needs o have the same name
:: as the destination file, and you also have to use an absolute path.
if exist %cygwin_dir% (
echo Cygwin appears to be pre-installed.
) else (
echo Downloading %src%
mkdir %dlroot%
bitsadmin /CREATE Anonymine_Cygwin_DL
bitsadmin /ADDFILE Anonymine_Cygwin_DL %src% %dl_setup%
bitsadmin /TRANSFER Anonymine_Cygwin_DL %src% %dl_setup%
echo Installing Cygwin
%dl_setup% --wait -q -R %cygwin_dir%
move %dl_setup% %cygwin_setup%
rmdir %dlroot%
)
echo Installing %python_pkg% and the game
%cygwin_setup% --wait -q -M -R %cygwin_dir% -P python -P make
:: bash -l to use the Cygwin $PATH rather than the MS %PATH%.
:: Then you'll need to go back to $OLDPWD.
%cygwin_dir%\bin\bash -lc 'echo "(Workaround): Do not remove!"'
%cygwin_dir%\bin\bash -lc 'cd $OLDPWD; ./configure -v; make; make install'
@echo off
:: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Where you want Cygwin to be installed:
set cygwin_dir=%userprofile%\Cygwin
:: Where you want the Cygwin installer to be placed, (including filename):
set cygwin_setup=%cygwin_dir%\setup.exe
:: Temporary, make sure this doesn't exist.
set dlroot=%userprofile%\Tmp-anonymine
:: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: URLs and valid destination file names.
set src64=https://cygwin.com/setup-x86_64.exe
set src32=https://cygwin.com/setup-x86.exe
set dl64=%dlroot%\setup-x86_64.exe
set dl32=%dlroot%\setup-x86.exe
:: 64/32
if exist %systemroot%\SysWOW64\ set src=%src64%
if exist %systemroot%\SysWOW64\ set dl_setup=%dl64%
if not exist %systemroot%\SysWOW64\ set src=%src32%
if not exist %systemroot%\SysWOW64\ set dl_setup=%dl32%