Skip to content

Commit c20b864

Browse files
committed
Rework_Sea_project
1 parent c27f0e5 commit c20b864

15 files changed

+462
-0
lines changed

Game-Galore/Sea_battle/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Little documentation for project
2+
3+
Sea_battle/ # Game project file
4+
Sea_battle/ai_py # AI logic for the game
5+
Sea_battle/battleship.py # The main file of the game through which it is launched
6+
Sea_battle/board.py # Representation of logic and implementation of the playing field
7+
Sea_battle/client.py # Client part of the game
8+
Sea_battle/game_save.json # Location where the save is stored
9+
Sea_battle/game.py # Game state management (including saves and save loads)
10+
Sea_battle/player.py # The player's representation of both himself and an AI opponent/second real player.
11+
Sea_battle/server.py # Server part of the game
12+
Sea_battle/ship.py # Ship Logic View
13+
14+
How to run?: Through the terminal in VS Code and/or PyCharm, enter the command "cd C:\Users\Your_name\Desktop\Your_file\SpectrumOfPython\Game-Galore\Sea_battle", then in terminal write "python battleship.py".
15+
16+
How to play: First, select an opponent (AI or a real player, whom you are currently playing), then choose your (and second player, when you play against real man) nickname and game is generated 10x10 field with 4 types of ships. 4 one-cell ships, 3 two-cell ships, 2 three-cell ships and 1 four-cell ship. Your task is to sink all enemy ships while preserving your own. The round goes until victory. You will have to select the field for defeat using numbers from 0 to 9 in a column and line, the enemy bot/player does the same.
17+
18+
In the future, the game will be updated and released on mobile, joystick and computer controls, and graphics and sound will also be developed.
19+
20+
Now... have fun!
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Game-Galore/Sea_battle/ai.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import random
2+
3+
class AIPlayer:
4+
def __init__(self, name):
5+
self.name = name
6+
self.previous_moves = set()
7+
8+
def make_move(self, board):
9+
while True:
10+
row = random.randint(0, len(board.grid) - 1)
11+
col = random.randint(0, len(board.grid[0]) - 1)
12+
if (row, col) not in self.previous_moves:
13+
self.previous_moves.add((row, col))
14+
return (row, col)

Game-Galore/Sea_battle/battleship.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from game import Game
2+
3+
def main():
4+
game = Game()
5+
game.play()
6+
7+
if __name__ == "__main__":
8+
main()

Game-Galore/Sea_battle/board.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from ship import Ship
2+
import random
3+
4+
class Board:
5+
def __init__(self):
6+
self.size = 10
7+
self.grid = [[0 for _ in range(self.size)] for _ in range(self.size)]
8+
self.ships = []
9+
self.ship_counts = {
10+
1: 4,
11+
2: 3,
12+
3: 2,
13+
4: 1
14+
}
15+
self.shots_taken = set()
16+
17+
def place_ship(self, ship, start_row, start_col, orientation):
18+
if self.can_place_ship(ship, start_row, start_col, orientation):
19+
ship.place(start_row, start_col, orientation)
20+
self.ships.append(ship)
21+
for position in ship.positions:
22+
row, col = position
23+
self.grid[row][col] = 1
24+
print(f"Placed ship of length {ship.length} at {start_row}, {start_col} in {orientation} orientation.")
25+
else:
26+
print(f"Cannot place ship of length {ship.length} at {start_row}, {start_col} in {orientation} orientation.")
27+
raise ValueError("Cannot place ship here!")
28+
29+
def can_place_ship(self, ship, row, col, orientation):
30+
if orientation == 'horizontal':
31+
if col + ship.length > self.size:
32+
return False
33+
return all(self.grid[row][col + i] == 0 for i in range(ship.length))
34+
elif orientation == 'vertical':
35+
if row + ship.length > self.size:
36+
return False
37+
return all(self.grid[row + i][col] == 0 for i in range(ship.length))
38+
return False
39+
40+
def receive_shot(self, row, col):
41+
print(f"Received shot at ({row}, {col})")
42+
self.shots_taken.add((row, col))
43+
if self.grid[row][col] == 1:
44+
for ship in self.ships:
45+
if self.is_hit(ship, row, col):
46+
ship.hit((row, col))
47+
self.grid[row][col] = 2
48+
if ship.is_sunk():
49+
print(f"Ship sunk at {ship.positions}!")
50+
return True
51+
self.grid[row][col] = -1
52+
print("Miss!")
53+
return False
54+
55+
def is_hit(self, ship, row, col):
56+
return (row, col) in ship.positions
57+
58+
def check_all_ships_sunk(self):
59+
return all(ship.is_sunk() for ship in self.ships)
60+
61+
def display(self, reveal=False):
62+
for row in range(self.size):
63+
for col in range(self.size):
64+
if self.grid[row][col] == 1 and not reveal:
65+
print('0', end=' ')
66+
elif self.grid[row][col] == -1:
67+
print('M', end=' ')
68+
else:
69+
print(self.grid[row][col], end=' ')
70+
print()
71+
72+
def setup_ships(self):
73+
self.ships = []
74+
for length, count in self.ship_counts.items():
75+
for _ in range(count):
76+
ship = Ship(length)
77+
placed = False
78+
while not placed:
79+
start_row = random.randint(0, self.size - 1)
80+
start_col = random.randint(0, self.size - 1)
81+
orientation = random.choice(['horizontal', 'vertical'])
82+
try:
83+
self.place_ship(ship, start_row, start_col, orientation)
84+
placed = True
85+
except ValueError:
86+
continue
87+
88+
def is_location_shot(self, row, col):
89+
return (row, col) in self.shots_taken

Game-Galore/Sea_battle/client.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import socket
2+
import json
3+
4+
class GameClient:
5+
def __init__(self, host='localhost', port=12345):
6+
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
7+
self.client_socket.connect((host, port))
8+
9+
def send_move(self, row, col):
10+
move_data = {'action': 'move', 'row': row, 'col': col}
11+
self.client_socket.send(json.dumps(move_data).encode('utf-8'))
12+
13+
def get_game_state(self):
14+
self.client_socket.send("get_state".encode('utf-8'))
15+
data = self.client_socket.recv(1024).decode('utf-8')
16+
return json.loads(data)
17+
18+
def play(self):
19+
while True:
20+
game_state = self.get_game_state()
21+
print(f"Current player: {game_state['current_player']}")
22+
print("Board 1:", game_state['board1'])
23+
print("Board 2:", game_state['board2'])
24+
25+
if game_state['is_game_over']:
26+
print("Game Over!")
27+
break
28+
29+
while True:
30+
try:
31+
row = int(input("Enter row (0-9): "))
32+
col = int(input("Enter column (0-9): "))
33+
if row < 0 or row >= 10 or col < 0 or col >= 10:
34+
print("Coordinates out of bounds! Please enter values between 0 and 9.")
35+
continue
36+
self.send_move(row, col)
37+
break
38+
except ValueError:
39+
print("Invalid input! Please enter integers.")
40+
41+
if __name__ == "__main__":
42+
client = GameClient()
43+
client.play()

Game-Galore/Sea_battle/game.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import json
2+
import random
3+
from board import Board
4+
from player import HumanPlayer, AIPlayer
5+
from ship import Ship
6+
7+
class Game:
8+
def __init__(self):
9+
opponent_choice = input("Do you want to play against AI or another player? (AI/player): ")
10+
if opponent_choice.lower() == "ai":
11+
self.ai_player = AIPlayer("AI")
12+
self.human_player = HumanPlayer()
13+
self.board1 = Board()
14+
self.board2 = Board()
15+
self.board1.setup_ships()
16+
self.ai_setup_ships()
17+
else:
18+
self.human_player = HumanPlayer()
19+
self.second_player = HumanPlayer()
20+
self.board1 = Board()
21+
self.board2 = Board()
22+
self.board1.setup_ships()
23+
self.board2.setup_ships()
24+
25+
self.current_player = self.human_player
26+
self.is_game_over = False
27+
self.shots_taken = set()
28+
29+
def ai_setup_ships(self):
30+
ships_to_place = [Ship(1) for _ in range(4)] + [Ship(2) for _ in range(3)] + [Ship(3) for _ in range(2)] + [Ship(4) for _ in range(1)]
31+
32+
for ship in ships_to_place:
33+
placed = False
34+
while not placed:
35+
try:
36+
start_row = random.randint(0, self.board2.size - 1)
37+
start_col = random.randint(0, self.board2.size - 1)
38+
orientation = random.choice(['horizontal', 'vertical'])
39+
self.board2.place_ship(ship, start_row, start_col, orientation)
40+
placed = True
41+
except ValueError:
42+
continue
43+
44+
def shoot(self, row, col):
45+
if (row, col) in self.shots_taken:
46+
print("You have already shot at this position!")
47+
return False
48+
self.shots_taken.add((row, col))
49+
50+
target_board = self.board2 if self.current_player == self.human_player else self.board1
51+
52+
print(f"Player {self.current_player.name} is shooting at ({row}, {col})")
53+
hit = target_board.receive_shot(row, col)
54+
if hit:
55+
print("Hit!")
56+
else:
57+
print("Miss!")
58+
59+
self.check_game_over()
60+
return hit
61+
62+
def check_game_over(self):
63+
if self.board2.check_all_ships_sunk():
64+
self.is_game_over = True
65+
print(f"{self.current_player.name} wins!")
66+
self.ask_to_play_again()
67+
68+
def ask_to_play_again(self):
69+
choice = input("Want to play again? (yes/no): ")
70+
if choice.lower() == 'yes':
71+
self.reset_game()
72+
else:
73+
print("Thanks for playing!")
74+
75+
def reset_game(self):
76+
self.board1 = Board()
77+
self.board2 = Board()
78+
self.current_player = self.human_player
79+
self.is_game_over = False
80+
81+
opponent_choice = input("Do you want to play against AI or another player? (AI/player): ")
82+
if opponent_choice.lower() == "ai":
83+
self.ai_player = AIPlayer("AI")
84+
self.board1.setup_ships()
85+
self.ai_setup_ships()
86+
else:
87+
self.second_player = HumanPlayer()
88+
self.board1.setup_ships()
89+
self.board2.setup_ships()
90+
91+
def save_game(self, filename):
92+
game_state = {
93+
'board1': self.board1.grid,
94+
'board2': self.board2.grid,
95+
'current_player': self.current_player.name,
96+
'is_game_over': self.is_game_over
97+
}
98+
with open(filename, 'w') as f:
99+
json.dump(game_state, f)
100+
101+
def load_game(self, filename):
102+
with open(filename, 'r') as f:
103+
game_state = json.load(f)
104+
self.board1.grid = game_state['board1']
105+
self.board2.grid = game_state['board2']
106+
self.current_player = self.human_player if game_state['current_player'] == self.human_player.name else self.ai_player
107+
self.is_game_over = game_state['is_game_over']
108+
109+
def display_boards(self):
110+
print("Your Board:")
111+
self.board1.display(reveal=True)
112+
print("\nOpponent's Board (Hidden view):")
113+
self.board2.display()
114+
115+
def play(self):
116+
while not self.is_game_over:
117+
print(f"Current player: {self.current_player.name}")
118+
self.display_boards()
119+
120+
if self.current_player.is_ai:
121+
row, col = self.current_player.get_move()
122+
print(f"AI chose coordinates: ({row}, {col})")
123+
else:
124+
command = input("Enter 'save' to save or 'load' to load the game, or make a move (row col): ")
125+
if command.lower() == 'save':
126+
self.save_game('game_save.json')
127+
print("Game saved.")
128+
continue
129+
elif command.lower() == 'load':
130+
self.load_game('game_save.json')
131+
print("Game loaded.")
132+
continue
133+
134+
try:
135+
row, col = map(int, command.split())
136+
except ValueError:
137+
print("Invalid input. Please enter coordinates in 'row col' format.")
138+
continue
139+
140+
hit = self.shoot(row, col)
141+
if not hit:
142+
self.current_player = self.ai_player if self.current_player == self.human_player else self.human_player
143+
144+
if __name__ == "__main__":
145+
game = Game()
146+
game.play()

0 commit comments

Comments
 (0)