first commit

This commit is contained in:
Rodolphe Breard 2015-08-20 12:44:32 +02:00
commit 1e07310ed5
18 changed files with 408 additions and 0 deletions

59
.gitignore vendored Normal file
View file

@ -0,0 +1,59 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Misc stuff
*~
\#*
.\#*

13
LICENSE.txt Normal file
View file

@ -0,0 +1,13 @@
Copyright (c) 2015 Rodolphe Breard
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.

37
README.md Normal file
View file

@ -0,0 +1,37 @@
# Happy Slot Machine
This software is a python slot machine that cheats on the users.
## Usage
```ShellSession
$ python happy_slot_machine.py
```
This software has been written for python 3 but should also work on python 2.
## Numbers selection
Instead of drawing 3 random numbers, we draw 4 of them. If they are not all different or identical, two identical numbers are set on the first two positions and a different one in the third. Then, the three first are returned. Using 10 digits, this leads to a quite low chance of success and the probabilities to display a losing combination starting with 2 identical numbers are significantly high.
A perspicacious player could suspect the machine is cheating by observing that, in case of two identical numbers, the two first are always the identical ones. In order to prevent that, in this particular case, we add an extra rule: there is 25% chances first and third numbers are permuted and 25% chances second and third numbers are permuted.
* P(success) = 1/(10^3) = 0.001
* P(failure) = 1 - P(success) = 0.999
* P(all different) = (9*8*7) / 10^3 = 0.504
* P(failure & two identical) = 1 - P(success) - P(all different) = 0.495
* P(failure & first identical to second) = P(two identical) * 0.5 = 0.2475
* P(failure & first identical to third) = P(two identical) * 0.25 = 0.12375
* P(failure & second identical to third) = P(two identical) * 0.25 = 0.12375
In comparison, a non-manipulated machine would have the following probabilities:
* P(success) = 1/(10^2) = 0.01
* P(failure) = 1 - P(success) = 0.99
* P(all different) = (9*8) / 10^2 = 0.72
* P(failure & two identical) = 1 - P(success) - P(all different) = 0.27
* P(failure & first identical to second) = P(two identical) * (1/3) = 0.09
* P(failure & first identical to third) = P(two identical) * (1/3) = 0.09
* P(failure & second identical to third) = P(two identical) * (1/3) = 0.09

6
assets/0.txt Normal file
View file

@ -0,0 +1,6 @@
____
.' '.
| .--. |
| | | |
| `--' |
'.____.'

6
assets/1.txt Normal file
View file

@ -0,0 +1,6 @@
__
/ |
`| |
| |
_| |_
|_____|

6
assets/2.txt Normal file
View file

@ -0,0 +1,6 @@
_____
/ ___ `.
|_/___) |
.'____.'
/ /_____
|_______|

6
assets/3.txt Normal file
View file

@ -0,0 +1,6 @@
______
/ ____ `.
`' __) |
_ |__ '.
| \____) |
\______.'

6
assets/4.txt Normal file
View file

@ -0,0 +1,6 @@
_ _
| | | |
| |__| |_
|____ _|
_| |_
|_____|

6
assets/5.txt Normal file
View file

@ -0,0 +1,6 @@
_______
| _____|
| |____
'_.____''.
| \____) |
\______.'

6
assets/6.txt Normal file
View file

@ -0,0 +1,6 @@
______
.' ____ \
| |____\_|
| '____`'.
| (____) |
'.______.'

6
assets/7.txt Normal file
View file

@ -0,0 +1,6 @@
_______
| ___ |
|_/ / /
/ /
/ /
/_/

6
assets/8.txt Normal file
View file

@ -0,0 +1,6 @@
____
.' __ '.
| (__) |
.`____'.
| (____) |
`.______.'

6
assets/9.txt Normal file
View file

@ -0,0 +1,6 @@
______
.' ____ '.
| (____) |
'_.____. |
| \____| |
\______,'

6
assets/failure.txt Normal file
View file

@ -0,0 +1,6 @@
__ __ _ _ _
\ \ / / | | | | | |
\ V /___ _ _ | | ___ ___| |_| |
\ // _ \| | | | | |/ _ \/ __| __| |
| | (_) | |_| | | | (_) \__ \ |_|_|
\_/\___/ \__,_| |_|\___/|___/\__(_)

6
assets/reset.txt Normal file
View file

@ -0,0 +1,6 @@

11
assets/slot.txt Normal file
View file

@ -0,0 +1,11 @@
.----------------.
| .--------------. |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| '--------------' |
'----------------'

6
assets/success.txt Normal file
View file

@ -0,0 +1,6 @@
__ __ _
\ \ / / | |
\ V /___ _ _ __ _____ _ __ | |
\ // _ \| | | | \ \ /\ / / _ \| '_ \| |
| | (_) | |_| | \ V V / (_) | | | |_|
\_/\___/ \__,_| \_/\_/ \___/|_| |_(_)

210
happy_slot_machine.py Executable file
View file

@ -0,0 +1,210 @@
#!/bin/env python
#
# Copyright (c) 2015 Rodolphe Breard
#
# 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.
#
"""
Happy Slot Machine
This software is a python slot machine that cheats on the users. The numbers
selection function is designed so it is very unlikely to get three identical
numbers and increases the chances for the two firsts numbers to be the same.
"""
from collections import Counter
from random import randint
import curses
import time
import os
def get_asset(asset_name):
'''
Loads an asset in memory.
'''
file_name = '{}.txt'.format(asset_name)
asset_path = os.path.join('assets', file_name)
with open(asset_path) as f:
return [l.rstrip('\n') for l in f.readlines()]
slot_asset = get_asset('slot')
numbers_assets = [get_asset(n) for n in range(10)]
results_assets = {
'success': get_asset('success'),
'failure': get_asset('failure'),
'reset': get_asset('reset'),
}
def get_numbers():
'''
Returns a list of 3 not-so-random numbers.
See the attached README.md for more details.
'''
nbs = [randint(0, 9) for _ in range(4)]
set_len = len(set(nbs))
if set_len in [2, 3]:
nbs.sort(key=Counter(nbs).get, reverse=True)
nbs[2], nbs[3] = nbs[3], nbs[2]
rand_position = randint(1, 100)
if rand_position < 50:
nbs[0], nbs[2] = nbs[2], nbs[0]
elif rand_position < 25:
nbs[1], nbs[2] = nbs[1], nbs[0]
return nbs[:3]
def draw_result(stdscr, status):
'''
Draws the status of the current round.
stdscr: curses window object
status: string, must be either "success", "failure" or "reset"
'''
for i, line in enumerate(results_assets[status]):
stdscr.addstr(i + 13, 1, line)
stdscr.refresh()
def draw_slot(stdscr, offset):
'''
Draws an empty slot.
stdscr: curses window object
offset: integer representing the slot's position
'''
off = offset * (len(slot_asset[0]) + 3) + 1
for i, line in enumerate(slot_asset):
stdscr.addstr(i + 2, off, line)
def draw_slots(stdscr):
'''
Draws the 3 empty slots.
stdscr: curses window object
'''
for i in range(3):
draw_slot(stdscr, i)
stdscr.refresh()
def draw_raw_number(stdscr, nb, offset):
'''
Draws a number in a given slot.
stdscr: curses window object
nb: integer representing number to display
offset: integer representing the slot's position
'''
nb = numbers_assets[nb]
off = offset * (len(nb[0]) + 13) + 6
for i, line in enumerate(nb):
stdscr.addstr(i + 4, off, line)
stdscr.refresh()
def random_excepted(nb):
'''
Returns a random number that cannot be the one passed as a parameter.
nb: integer representing the number to avoid
'''
while True:
n = randint(0, 9)
if n != nb:
return n
def numbers_to_display(nb):
'''
Yields a series of numbers that should be displayed on a slot.
nb: integer representing the last number to be yielded
'''
n = None
for _ in range(10):
time.sleep(0.15)
n = random_excepted(n)
yield n
yield nb
def draw_number(stdscr, nb, offset):
'''
Draws a number in a given slot with an animation.
stdscr: curses window object
nb: integer representing number to display
offset: integer representing the slot's position
'''
for n in numbers_to_display(nb):
draw_raw_number(stdscr, n, offset)
def play(stdscr):
'''
Plays a new round.
stdscr: curses window object
'''
nbs = get_numbers()
draw_slots(stdscr)
draw_result(stdscr, 'reset')
for i, nb in enumerate(nbs):
draw_number(stdscr, nb, i)
draw_result(stdscr, 'success' if len(set(nbs)) == 1 else 'failure')
def clean_input(stdscr):
'''
Removes all unread data from the standard input.
'''
stdscr.nodelay(1)
while stdscr.getch() != -1:
pass
stdscr.nodelay(0)
def main(stdscr):
'''
Initialize the screen and the commands.
stdscr: curses window object
'''
height, width = stdscr.getmaxyx()
curses.curs_set(0)
stdscr.clear()
stdscr.addstr(" SLOT MACHINE", curses.A_REVERSE)
stdscr.chgat(-1, curses.A_REVERSE)
h = height - 1
stdscr.addstr(h, 0, " Press Q to quit, P to play.", curses.A_REVERSE)
stdscr.chgat(h, 0, -1, curses.A_REVERSE)
draw_slots(stdscr)
while True:
stdscr.refresh()
clean_input(stdscr)
key = stdscr.getch()
if key in [ord('q'), ord('Q')]:
break
elif key in [ord('p'), ord('P')]:
play(stdscr)
if __name__ == '__main__':
curses.wrapper(main)