2025-07-25 22:31:35 +02:00
import pygame
import sys
from constants import *
2025-07-26 14:13:55 +02:00
from player import *
2025-07-27 20:10:59 +02:00
import copy
2025-07-25 22:31:35 +02:00
2025-07-27 16:02:25 +02:00
def print_board ( board ) :
for i in range ( BOARD_SIZE ) :
for j in range ( BOARD_SIZE ) :
print ( f " { board [ i ] [ j ] } " , end = " " )
print ( )
print ( )
2025-07-25 22:31:35 +02:00
def main ( ) :
print ( " Starting BattleShip! " )
pygame . init ( )
if pygame . get_init ( ) == False :
pygame . quit ( )
sys . exit ( 1 )
2025-07-26 14:03:13 +02:00
print ( " Please input your list of positions, from smallest ship to the largest, for your ships. " )
2025-07-26 20:41:16 +02:00
print ( " Format: a[A]1-a[A]5 b[B]2-b[B]3. [A] means it can either be upper or lower case. Please input the positions from lowest to highest. " )
print ( " You must have 5 ships. The ships can be of any size between 1 and 5. " )
print ( " Have fun. " )
2025-07-26 14:03:13 +02:00
good_inp = False
player_board = [ ]
enemy_board = [ ]
2025-07-27 16:02:25 +02:00
2025-07-26 14:03:13 +02:00
while good_inp == False :
inp = input ( )
2025-07-27 16:02:25 +02:00
good_inp , player_board , ship_pos = check_valid_input ( inp )
2025-07-27 20:10:59 +02:00
enemy_board = copy . deepcopy ( player_board )
2025-07-26 14:03:13 +02:00
2025-07-28 09:20:41 +02:00
player = Player ( player_board , ship_pos . copy ( ) , " Player " )
enemy = Player ( enemy_board , ship_pos . copy ( ) , " Enemy " )
2025-07-26 14:13:55 +02:00
2025-07-28 09:53:33 +02:00
#print_board(player_board)
2025-07-26 14:03:13 +02:00
2025-07-25 22:31:35 +02:00
screen = pygame . display . set_mode ( ( SCREEN_WIDTH , SCREEN_HEIGHT ) )
2025-07-27 20:10:59 +02:00
turn_counter = 0
2025-07-26 20:41:16 +02:00
first_iteration = True
2025-07-27 20:10:59 +02:00
is_enemy_turn = False
2025-07-25 22:31:35 +02:00
while True :
for event in pygame . event . get ( ) :
if event . type == pygame . QUIT :
print ( " Quitting Battleships " )
return
2025-07-26 14:49:49 +02:00
pygame . Surface . fill ( screen , ( 255 , 255 , 255 ) )
2025-07-25 22:31:35 +02:00
2025-07-26 20:41:16 +02:00
if first_iteration == False :
2025-07-27 20:10:59 +02:00
if is_enemy_turn == False :
player . update ( enemy )
is_enemy_turn = True
else :
enemy . random_shoot ( player )
is_enemy_turn = False
2025-07-26 20:41:16 +02:00
else :
first_iteration = False
2025-07-28 09:20:41 +02:00
if check_win ( player , enemy ) == True :
print ( f " { player . name } won! " )
sys . exit ( 0 )
if check_win ( enemy , player ) == True :
print ( f " { player . name } won! " )
sys . exit ( 0 )
player . draw ( screen , enemy )
2025-07-25 22:31:35 +02:00
pygame . display . flip ( ) #refresh screen
2025-07-27 20:10:59 +02:00
turn_counter + = 1
print ( " turn: " , turn_counter )
2025-07-25 22:31:35 +02:00
2025-07-26 14:03:13 +02:00
2025-07-28 09:20:41 +02:00
def check_win ( player , enemy ) :
print ( f " checking win for: { player . name } " )
for i in range ( 0 , BOARD_SIZE ) :
for j in range ( 0 , BOARD_SIZE ) :
if enemy . board [ i ] [ j ] == 0b01 :
return False
return True
2025-07-26 14:03:13 +02:00
def check_valid_input ( inp ) :
2025-07-27 16:02:25 +02:00
ship_pos = [ ]
2025-07-26 14:03:13 +02:00
s = inp . split ( ' ' )
2025-07-28 09:53:33 +02:00
#print("s", s)
2025-07-26 14:03:13 +02:00
board = [ ]
2025-07-26 20:41:16 +02:00
for i in range ( BOARD_SIZE ) :
2025-07-26 14:03:13 +02:00
board . append ( [ ] )
2025-07-26 20:41:16 +02:00
for _ in range ( BOARD_SIZE ) :
2025-07-26 14:03:13 +02:00
board [ i ] . append ( 0 )
if len ( s ) != 5 :
print ( " Not valid input. Please input again " )
2025-07-27 16:02:25 +02:00
return ( False , board , ship_pos )
2025-07-26 14:03:13 +02:00
else :
2025-07-26 20:41:16 +02:00
count = 0
2025-07-26 14:03:13 +02:00
for position in s :
2025-07-26 20:41:16 +02:00
count + = 1
2025-07-28 09:53:33 +02:00
#print("c", count)
2025-07-26 14:03:13 +02:00
position = position . lower ( )
t = position . split ( " - " )
2025-07-28 09:53:33 +02:00
#print("t", t)
2025-07-27 16:02:25 +02:00
ship_pos . append ( ( t [ 0 ] , t [ 1 ] ) )
2025-07-26 14:03:13 +02:00
2025-07-28 09:20:41 +02:00
if t [ 0 ] [ 0 ] == t [ 1 ] [ 0 ] and ord ( t [ 0 ] [ 0 ] ) > = 97 and ord ( t [ 0 ] [ 0 ] ) < = 106 and ord ( t [ 1 ] [ 0 ] ) > = 97 and ord ( t [ 1 ] [ 0 ] ) < = 106 : #check if the fist chars match
2025-07-26 14:03:13 +02:00
if int ( t [ 0 ] [ 1 ] ) > = 0 and int ( t [ 0 ] [ 1 ] ) < = 9 and int ( t [ 1 ] [ 1 ] ) > = 0 and int ( t [ 1 ] [ 1 ] ) < = 9 and int ( t [ 0 ] [ 1 ] ) != int ( t [ 1 ] [ 1 ] ) and abs ( int ( t [ 0 ] [ 1 ] ) - int ( t [ 1 ] [ 1 ] ) ) + 1 < 6 : #check if number is in correct range
if int ( t [ 0 ] [ 1 ] ) > int ( t [ 1 ] [ 1 ] ) :
step = - 1
else :
step = 1
for column in range ( int ( t [ 0 ] [ 1 ] ) , int ( t [ 1 ] [ 1 ] ) + 1 , step ) :
if board [ ord ( t [ 0 ] [ 0 ] ) - 97 ] [ column ] == 0b01 :
print ( " this position is already taken! " )
2025-07-27 16:02:25 +02:00
return ( False , board , ship_pos )
2025-07-26 14:03:13 +02:00
board [ ord ( t [ 0 ] [ 0 ] ) - 97 ] [ column ] = 0b01 #first means if it is hit, second means placement
2025-07-28 09:53:33 +02:00
#print_board(board)
2025-07-26 14:03:13 +02:00
else :
2025-07-28 09:53:33 +02:00
#print("e1")
2025-07-27 16:02:25 +02:00
return ( False , board , ship_pos )
2025-07-26 14:03:13 +02:00
elif t [ 0 ] [ 1 ] == t [ 1 ] [ 1 ] and int ( t [ 0 ] [ 1 ] ) < = 9 and int ( t [ 1 ] [ 1 ] ) > = 0 and int ( t [ 1 ] [ 1 ] ) < = 9 and abs ( int ( t [ 0 ] [ 1 ] ) - int ( t [ 1 ] [ 1 ] ) ) + 1 < 6 :
2025-07-28 09:20:41 +02:00
if ord ( t [ 0 ] [ 0 ] ) > = 97 and ord ( t [ 0 ] [ 0 ] ) < = 106 and ord ( t [ 1 ] [ 0 ] ) > = 97 and ord ( t [ 1 ] [ 0 ] ) < = 106 and t [ 0 ] [ 0 ] != t [ 1 ] [ 0 ] :
2025-07-26 14:03:13 +02:00
if ord ( t [ 0 ] [ 0 ] ) > ord ( t [ 1 ] [ 0 ] ) :
step = - 1
else :
step = 1
for row in range ( ord ( t [ 0 ] [ 0 ] ) - 97 , ord ( t [ 1 ] [ 0 ] ) - 97 + 1 , step ) :
if board [ row ] [ int ( t [ 0 ] [ 1 ] ) ] == 0b01 :
print ( " this position is already taken! " )
2025-07-27 16:02:25 +02:00
return ( False , board , ship_pos )
2025-07-26 14:03:13 +02:00
board [ row ] [ int ( t [ 0 ] [ 1 ] ) ] = 0b01 #first means if it is hit, second means placement
2025-07-28 09:53:33 +02:00
#print_board(board)
2025-07-26 14:03:13 +02:00
else :
2025-07-28 09:53:33 +02:00
#print("e2")
2025-07-27 16:02:25 +02:00
return ( False , board , ship_pos )
2025-07-26 14:03:13 +02:00
2025-07-28 09:53:33 +02:00
#print("e3")
2025-07-27 16:02:25 +02:00
return ( True , board , ship_pos )
2025-07-26 14:03:13 +02:00
2025-07-25 22:31:35 +02:00
if __name__ == " __main__ " :
main ( )