mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 07:10:42 -08:00
Python: Add test for 9 / 10 / 11 / 12
This commit is contained in:
@@ -8,7 +8,9 @@ from acey_ducey import play_game
|
|||||||
|
|
||||||
|
|
||||||
@mock.patch("random.shuffle")
|
@mock.patch("random.shuffle")
|
||||||
def test_play_game_lose(mock_random_shuffle, monkeypatch: MonkeyPatch, capsys: CaptureFixture) -> None:
|
def test_play_game_lose(
|
||||||
|
mock_random_shuffle, monkeypatch: MonkeyPatch, capsys: CaptureFixture
|
||||||
|
) -> None:
|
||||||
monkeypatch.setattr("sys.stdin", io.StringIO("100\n100"))
|
monkeypatch.setattr("sys.stdin", io.StringIO("100\n100"))
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|||||||
0
09_Battle/python/battle.py
Normal file → Executable file
0
09_Battle/python/battle.py
Normal file → Executable file
0
09_Battle/python/battle_oo.py
Normal file → Executable file
0
09_Battle/python/battle_oo.py
Normal file → Executable file
27
09_Battle/python/test_battle.py
Normal file
27
09_Battle/python/test_battle.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import io
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from _pytest.monkeypatch import MonkeyPatch
|
||||||
|
|
||||||
|
from battle import main as main_one
|
||||||
|
from battle_oo import main as main_oo
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"main",
|
||||||
|
[main_one, main_oo],
|
||||||
|
)
|
||||||
|
def test_main(monkeypatch: MonkeyPatch, main: Callable[[], None]) -> None:
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"sys.stdin",
|
||||||
|
io.StringIO(
|
||||||
|
"1,1\n1,2\n1,3\n1,4\n1,5\n1,6\n"
|
||||||
|
"2,1\n2,2\n2,3\n2,4\n2,5\n2,6\n"
|
||||||
|
"3,1\n3,2\n3,3\n3,4\n3,5\n3,6\n"
|
||||||
|
"4,1\n4,2\n4,3\n4,4\n4,5\n4,6\n"
|
||||||
|
"5,1\n5,2\n5,3\n5,4\n5,5\n5,6\n"
|
||||||
|
"6,1\n6,2\n6,3\n6,4\n6,5\n6,6\n"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
main()
|
||||||
17
10_Blackjack/python/test_blackjack.py
Normal file
17
10_Blackjack/python/test_blackjack.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import io
|
||||||
|
|
||||||
|
from _pytest.monkeypatch import MonkeyPatch
|
||||||
|
from _pytest.capture import CaptureFixture
|
||||||
|
|
||||||
|
from blackjack import main
|
||||||
|
|
||||||
|
|
||||||
|
def test_blackjack(monkeypatch: MonkeyPatch, capsys: CaptureFixture[str]) -> None:
|
||||||
|
nb_players = 1
|
||||||
|
instructions = "y"
|
||||||
|
bet = 100
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"sys.stdin",
|
||||||
|
io.StringIO(f"{nb_players}\n{instructions}\n\n{bet}\ns\nn\n"),
|
||||||
|
)
|
||||||
|
main()
|
||||||
@@ -43,12 +43,11 @@ def generate_enemy_positions() -> Set[int]:
|
|||||||
return set(positions[:4])
|
return set(positions[:4])
|
||||||
|
|
||||||
|
|
||||||
def is_valid_position(pos) -> bool:
|
def is_valid_position(pos: int) -> bool:
|
||||||
return pos in positions_list()
|
return pos in positions_list()
|
||||||
|
|
||||||
|
|
||||||
def prompt_for_player_positions() -> Set[int]:
|
def prompt_for_player_positions() -> Set[int]:
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
raw_positions = input("WHAT ARE YOUR FOUR POSITIONS? ")
|
raw_positions = input("WHAT ARE YOUR FOUR POSITIONS? ")
|
||||||
positions = {int(pos) for pos in raw_positions.split()}
|
positions = {int(pos) for pos in raw_positions.split()}
|
||||||
@@ -75,7 +74,13 @@ def prompt_player_for_target() -> int:
|
|||||||
return target
|
return target
|
||||||
|
|
||||||
|
|
||||||
def attack(target, positions, hit_message, miss_message, progress_messages) -> bool:
|
def attack(
|
||||||
|
target: int,
|
||||||
|
positions: Set[int],
|
||||||
|
hit_message: str,
|
||||||
|
miss_message: str,
|
||||||
|
progress_messages: str,
|
||||||
|
) -> bool:
|
||||||
"""Performs attack procedure returning True if we are to continue."""
|
"""Performs attack procedure returning True if we are to continue."""
|
||||||
|
|
||||||
if target in positions:
|
if target in positions:
|
||||||
@@ -89,9 +94,12 @@ def attack(target, positions, hit_message, miss_message, progress_messages) -> b
|
|||||||
|
|
||||||
|
|
||||||
def init_enemy() -> Callable[[], int]:
|
def init_enemy() -> Callable[[], int]:
|
||||||
"""Returns a closure analogous to prompt_player_for_target. Will
|
"""
|
||||||
choose from a unique sequence of positions to avoid picking the
|
Return a closure analogous to prompt_player_for_target.
|
||||||
same position twice."""
|
|
||||||
|
Will choose from a unique sequence of positions to avoid picking the
|
||||||
|
same position twice.
|
||||||
|
"""
|
||||||
|
|
||||||
position_sequence = positions_list()
|
position_sequence = positions_list()
|
||||||
random.shuffle(position_sequence)
|
random.shuffle(position_sequence)
|
||||||
|
|||||||
17
11_Bombardment/python/test_bombardment.py
Normal file
17
11_Bombardment/python/test_bombardment.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import io
|
||||||
|
|
||||||
|
from _pytest.monkeypatch import MonkeyPatch
|
||||||
|
|
||||||
|
from bombardment import play
|
||||||
|
|
||||||
|
|
||||||
|
def test_bombardment(monkeypatch: MonkeyPatch) -> None:
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"sys.stdin",
|
||||||
|
io.StringIO(
|
||||||
|
"\n1 2 3 4\n6\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"
|
||||||
|
"\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20"
|
||||||
|
"\n21\n22\n23\n24\n25"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
play()
|
||||||
16
12_Bombs_Away/python/test_bombs_away.py
Normal file
16
12_Bombs_Away/python/test_bombs_away.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import io
|
||||||
|
|
||||||
|
from _pytest.monkeypatch import MonkeyPatch
|
||||||
|
|
||||||
|
from bombs_away import play_game
|
||||||
|
|
||||||
|
|
||||||
|
def test_bombs_away(monkeypatch: MonkeyPatch) -> None:
|
||||||
|
side = 1
|
||||||
|
target = 1
|
||||||
|
missions = 1
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"sys.stdin",
|
||||||
|
io.StringIO(f"{side}\n{target}\n{missions}\n3\n50"),
|
||||||
|
)
|
||||||
|
play_game()
|
||||||
@@ -40,19 +40,9 @@
|
|||||||
"BOARD_WIDTH = 10\n",
|
"BOARD_WIDTH = 10\n",
|
||||||
"BOARD_HEIGHT = 10\n",
|
"BOARD_HEIGHT = 10\n",
|
||||||
"\n",
|
"\n",
|
||||||
"SHIPS = [ (\"BATTLESHIP\", 5),\n",
|
"SHIPS = [(\"BATTLESHIP\", 5), (\"CRUISER\", 3), (\"DESTROYER<A>\", 2), (\"DESTROYER<B>\", 2)]\n",
|
||||||
" (\"CRUISER\", 3),\n",
|
"\n",
|
||||||
" (\"DESTROYER<A>\", 2),\n",
|
"VALID_MOVES = [[-1, 0], [-1, 1], [0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1]]"
|
||||||
" (\"DESTROYER<B>\", 2) ]\n",
|
|
||||||
" \n",
|
|
||||||
"VALID_MOVES = [[-1, 0],\n",
|
|
||||||
" [-1, 1],\n",
|
|
||||||
" [ 0, 1],\n",
|
|
||||||
" [ 1, 1],\n",
|
|
||||||
" [ 1, 0],\n",
|
|
||||||
" [ 1,-1],\n",
|
|
||||||
" [ 0,-1],\n",
|
|
||||||
" [-1,-1]]"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -73,9 +63,9 @@
|
|||||||
"# x: integer between 1 and BOARD_HEIGHT\n",
|
"# x: integer between 1 and BOARD_HEIGHT\n",
|
||||||
"# y: integer between 1 and BOARD WIDTH\n",
|
"# y: integer between 1 and BOARD WIDTH\n",
|
||||||
"def random_x_y():\n",
|
"def random_x_y():\n",
|
||||||
" x = random.randrange(1,BOARD_WIDTH+1)\n",
|
" x = random.randrange(1, BOARD_WIDTH + 1)\n",
|
||||||
" y = random.randrange(1,BOARD_HEIGHT+1)\n",
|
" y = random.randrange(1, BOARD_HEIGHT + 1)\n",
|
||||||
" return (x,y)"
|
" return (x, y)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -92,8 +82,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"x,y = random_x_y()\n",
|
"x, y = random_x_y()\n",
|
||||||
"print (x,y)"
|
"print(x, y)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -105,19 +95,19 @@
|
|||||||
"# TODO: add an optional starting coordinate for testing\n",
|
"# TODO: add an optional starting coordinate for testing\n",
|
||||||
"# purposes\n",
|
"# purposes\n",
|
||||||
"def generate_ship_coordinates(ship):\n",
|
"def generate_ship_coordinates(ship):\n",
|
||||||
" \n",
|
"\n",
|
||||||
" # randomly generate starting x,y coordinates\n",
|
" # randomly generate starting x,y coordinates\n",
|
||||||
" start_x, start_y = random_x_y()\n",
|
" start_x, start_y = random_x_y()\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # using starting coordinates and the ship type,\n",
|
" # using starting coordinates and the ship type,\n",
|
||||||
" # generate a vector of possible directions the ship \n",
|
" # generate a vector of possible directions the ship\n",
|
||||||
" # could be placed. directions are numbered 0-7 along\n",
|
" # could be placed. directions are numbered 0-7 along\n",
|
||||||
" # points of the compass (N, NE, E, SE, S, SW, W, NW)\n",
|
" # points of the compass (N, NE, E, SE, S, SW, W, NW)\n",
|
||||||
" # clockwise. a vector of valid directions where the\n",
|
" # clockwise. a vector of valid directions where the\n",
|
||||||
" # ship does not go off the board is determined\n",
|
" # ship does not go off the board is determined\n",
|
||||||
" ship_len = SHIPS[ship][1] - 1\n",
|
" ship_len = SHIPS[ship][1] - 1\n",
|
||||||
" dirs = [False for x in range(8)]\n",
|
" dirs = [False for x in range(8)]\n",
|
||||||
" dirs[0] = (start_x - ship_len) >=1\n",
|
" dirs[0] = (start_x - ship_len) >= 1\n",
|
||||||
" dirs[2] = (start_y + ship_len) <= BOARD_WIDTH\n",
|
" dirs[2] = (start_y + ship_len) <= BOARD_WIDTH\n",
|
||||||
" dirs[1] = dirs[0] and dirs[2]\n",
|
" dirs[1] = dirs[0] and dirs[2]\n",
|
||||||
" dirs[4] = (start_x + ship_len) <= BOARD_HEIGHT\n",
|
" dirs[4] = (start_x + ship_len) <= BOARD_HEIGHT\n",
|
||||||
@@ -133,24 +123,23 @@
|
|||||||
" direction = directions[dir_idx]\n",
|
" direction = directions[dir_idx]\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # using the starting x,y, direction and ship\n",
|
" # using the starting x,y, direction and ship\n",
|
||||||
" # type, return the coordinates of each point \n",
|
" # type, return the coordinates of each point\n",
|
||||||
" # of the ship. VALID_MOVES is a staic array\n",
|
" # of the ship. VALID_MOVES is a staic array\n",
|
||||||
" # of coordinate offsets to walk from starting\n",
|
" # of coordinate offsets to walk from starting\n",
|
||||||
" # coordinate to the end coordinate in the \n",
|
" # coordinate to the end coordinate in the\n",
|
||||||
" # chosen direction\n",
|
" # chosen direction\n",
|
||||||
" ship_len = SHIPS[ship][1] - 1\n",
|
" ship_len = SHIPS[ship][1] - 1\n",
|
||||||
" d_x = VALID_MOVES[direction][0]\n",
|
" d_x = VALID_MOVES[direction][0]\n",
|
||||||
" d_y = VALID_MOVES[direction][1]\n",
|
" d_y = VALID_MOVES[direction][1]\n",
|
||||||
"\n",
|
"\n",
|
||||||
" coords = [(start_x,start_y)]\n",
|
" coords = [(start_x, start_y)]\n",
|
||||||
" x_coord = start_x\n",
|
" x_coord = start_x\n",
|
||||||
" y_coord = start_y\n",
|
" y_coord = start_y\n",
|
||||||
" for i in range(ship_len):\n",
|
" for i in range(ship_len):\n",
|
||||||
" x_coord = x_coord + d_x\n",
|
" x_coord = x_coord + d_x\n",
|
||||||
" y_coord = y_coord + d_y\n",
|
" y_coord = y_coord + d_y\n",
|
||||||
" coords.append((x_coord,y_coord))\n",
|
" coords.append((x_coord, y_coord))\n",
|
||||||
" return coords\n",
|
" return coords"
|
||||||
"\n"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -167,10 +156,9 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"\n",
|
|
||||||
"for ship in range(len(SHIPS)):\n",
|
"for ship in range(len(SHIPS)):\n",
|
||||||
" coords = generate_ship_coordinates(ship)\n",
|
" coords = generate_ship_coordinates(ship)\n",
|
||||||
" print(f'{SHIPS[ship][0]:15}',f'{SHIPS[ship][1]:2}',coords)"
|
" print(f\"{SHIPS[ship][0]:15}\", f\"{SHIPS[ship][1]:2}\", coords)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -180,8 +168,7 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"def create_blank_board():\n",
|
"def create_blank_board():\n",
|
||||||
" return [ [ None for y in range(BOARD_WIDTH)] \n",
|
" return [[None for y in range(BOARD_WIDTH)] for x in range(BOARD_HEIGHT)]"
|
||||||
" for x in range(BOARD_HEIGHT)]"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -201,19 +188,20 @@
|
|||||||
"def print_board(board):\n",
|
"def print_board(board):\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # print board header (column numbers)\n",
|
" # print board header (column numbers)\n",
|
||||||
" print(' ',end='')\n",
|
" print(\" \", end=\"\")\n",
|
||||||
" for z in range(BOARD_WIDTH):\n",
|
" for z in range(BOARD_WIDTH):\n",
|
||||||
" print(f'{z+1:3}',end='')\n",
|
" print(f\"{z+1:3}\", end=\"\")\n",
|
||||||
" print('')\n",
|
" print(\"\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
" for x in range(len(board)):\n",
|
" for x in range(len(board)):\n",
|
||||||
" print(f'{x+1:2}',end='')\n",
|
" print(f\"{x+1:2}\", end=\"\")\n",
|
||||||
" for y in range(len(board[x])):\n",
|
" for y in range(len(board[x])):\n",
|
||||||
" if(board[x][y] is None):\n",
|
" if board[x][y] is None:\n",
|
||||||
" print(f\"{' ':3}\",end='')\n",
|
" print(f\"{' ':3}\", end=\"\")\n",
|
||||||
" else:\n",
|
" else:\n",
|
||||||
" print(f\"{board[x][y]:3}\",end='')\n",
|
" print(f\"{board[x][y]:3}\", end=\"\")\n",
|
||||||
" print('')\n",
|
" print(\"\")\n",
|
||||||
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"computer_board = create_blank_board()\n",
|
"computer_board = create_blank_board()\n",
|
||||||
"print_board(computer_board)"
|
"print_board(computer_board)"
|
||||||
@@ -225,9 +213,9 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"def place_ship(board,coords,ship):\n",
|
"def place_ship(board, coords, ship):\n",
|
||||||
" for coord in coords:\n",
|
" for coord in coords:\n",
|
||||||
" board[coord[0]-1][coord[1]-1] = ship"
|
" board[coord[0] - 1][coord[1] - 1] = ship"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -247,8 +235,8 @@
|
|||||||
"# test place_ship\n",
|
"# test place_ship\n",
|
||||||
"board = create_blank_board()\n",
|
"board = create_blank_board()\n",
|
||||||
"coords = generate_ship_coordinates(0)\n",
|
"coords = generate_ship_coordinates(0)\n",
|
||||||
"print(f'{SHIPS[ship][0]:15}',f'{SHIPS[ship][1]:2}',coords)\n",
|
"print(f\"{SHIPS[ship][0]:15}\", f\"{SHIPS[ship][1]:2}\", coords)\n",
|
||||||
"place_ship(board,coords,0)\n",
|
"place_ship(board, coords, 0)\n",
|
||||||
"print_board(board)"
|
"print_board(board)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -281,6 +269,7 @@
|
|||||||
"# For example: 2 destroyers, length 2, one at\n",
|
"# For example: 2 destroyers, length 2, one at\n",
|
||||||
"# [(1,1),(2,2)] and other at [(2,1),(1,2)]\n",
|
"# [(1,1),(2,2)] and other at [(2,1),(1,2)]\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"\n",
|
||||||
"def generate_board():\n",
|
"def generate_board():\n",
|
||||||
" board = create_blank_board()\n",
|
" board = create_blank_board()\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -291,14 +280,15 @@
|
|||||||
" coords = generate_ship_coordinates(ship)\n",
|
" coords = generate_ship_coordinates(ship)\n",
|
||||||
" clear = True\n",
|
" clear = True\n",
|
||||||
" for coord in coords:\n",
|
" for coord in coords:\n",
|
||||||
" if board[coord[0]-1][coord[1]-1] is not None:\n",
|
" if board[coord[0] - 1][coord[1] - 1] is not None:\n",
|
||||||
" clear = False\n",
|
" clear = False\n",
|
||||||
" break\n",
|
" break\n",
|
||||||
" if clear:\n",
|
" if clear:\n",
|
||||||
" placed = True\n",
|
" placed = True\n",
|
||||||
" place_ship(board,coords,ship)\n",
|
" place_ship(board, coords, ship)\n",
|
||||||
" return board\n",
|
" return board\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"\n",
|
||||||
"print_board(generate_board())"
|
"print_board(generate_board())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -322,6 +312,7 @@
|
|||||||
" shots.append(random_x_y())\n",
|
" shots.append(random_x_y())\n",
|
||||||
" return shots\n",
|
" return shots\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"\n",
|
||||||
"shots = generate_shots(5)\n",
|
"shots = generate_shots(5)\n",
|
||||||
"print(shots)"
|
"print(shots)"
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user