Jump to content

BATTLESHIPS (game)


CodyBarrett
 Share

Recommended Posts

this is my implementation of the board game, yea it needs alot of work, like these:

---Vertical placement of ships

---AI search of nearby ships after a Hit

---"you sunk my battleship" messages

Opt ('GUIONEVENTMODE',1)
#include <GUICONSTANTSEX.AU3>
#include <WINDOWSCONSTANTS.au3>
#include <STATICCONSTANTS.au3>
#include <BUTTONCONSTANTS.au3>
#include <ARRAY.au3>

Global $l_size = 40

Dim $Player_gui_parent = 0
Dim $Player_gui_grid_ships[11][11]
Dim $Player_gui_grid_explosives[11][11]

Dim $AI_grid_ships[11][11]

Dim $Player_Ships_Location[15]

Dim $Player_HitsTaken
Dim $Player_HitsTaken_Label
Dim $AI_HitsTaken
Dim $AI_HitsTaken_Label
Dim $AI_WinCount = 0
Dim $Player_WinCount = 0

Dim $CurrentShip_to_be_Set = 5
Dim $CurrentTurn = 0
Dim $Player_HitsTaken = 0
Dim $AI_HitsTaken = 0
Dim $startup = 0
Dim $Alignment = 1
Dim $AI_last_hit_on_Player = 0&':'&0

Start ()


While 1
    If $Player_HitsTaken = 15 Or $AI_HitsTaken = 15 Then
        Dim $startup = 0
        If $AI_HitsTaken = 15 Then
            $Player_WinCount += 1
            If MsgBox (4,'Game Over!', 'Player Wins!' & @CRLF & _
                                'Score:' & @CRLF & _
                                    @TAB &  'AI:' & $AI_WinCount & @CRLF & _
                                    @TAB &  'Player:' & $Player_WinCount & @CRLF & _
                                'Play Again?','',WinGetHandle ('[active]')) = 6 Then
                GUIDelete ($Player_gui_parent)
                Start ()
            Else
                QUIT ()
            EndIf
        ElseIf $Player_HitsTaken = 15 Then
            $AI_WinCount += 1
            If MsgBox (4,'Game Over!', 'AI Wins!' & @CRLF & _
                                'Score:' & @CRLF & _
                                    @TAB &  'AI:' & $AI_WinCount & @CRLF & _
                                    @TAB &  'Player:' & $Player_WinCount & @CRLF & _
                                'Play Again?','',WinGetHandle ('[active]')) = 6 Then
                GUIDelete ($Player_gui_parent)
                Start ()
            Else
                QUIT ()
            EndIf
        EndIf
    Else
        If GUICtrlRead ($AI_HitsTaken_Label) <> 'AI has ' & 15-$AI_HitsTaken & ' Hits Left Before They Loze!' Then GUICtrlSetData ($AI_HitsTaken_Label,'AI has ' & 15-$AI_HitsTaken & ' Hits Left Before They Loze!')
        If GUICtrlRead ($Player_HitsTaken_Label) <> 'You have ' & 15-$Player_HitsTaken & ' Hits Left Before You Loze!' Then GUICtrlSetData ($Player_HitsTaken_Label,'You have ' & 15-$Player_HitsTaken & ' Hits Left Before You Loze!')
    EndIf
    Sleep (100)
WEnd
Func Start ()
    Local $y, $x, $AI_Alignment
    If $startup = 1 Then Return
    $startup = 1
    $CurrentShip_to_be_Set = 5
    $CurrentTurn = 0
    $Player_HitsTaken = 0
    $AI_HitsTaken = 0
    $Player_gui_parent = GUICreate ('BATTLESHIPS',(($l_size*10)*2)+30,($l_size*10)+(6*$l_size)+10)
    GUISetFont (10,999,'','Tahoma',$Player_gui_parent)
    GUICtrlSetDefBkColor (0xABCDEF,$Player_gui_parent)
    GUISetBkColor (0xABCDEF)
            GUICtrlCreateLabel ('Carrier :',10,($l_size*10)+$l_size,$l_size*5,$l_size,BitOR ($SS_CENTERIMAGE,$SS_CENTER))
            GUICtrlCreateLabel ('BattleShip :',10,($l_size*10)+(2*$l_size),$l_size*5,$l_size,BitOR ($SS_CENTERIMAGE,$SS_CENTER))
            GUICtrlCreateLabel ('Submarine :',10,($l_size*10)+(3*$l_size),$l_size*5,$l_size,BitOR ($SS_CENTERIMAGE,$SS_CENTER))
            GUICtrlCreateLabel ('Destroyer :',10,($l_size*10)+(4*$l_size),$l_size*5,$l_size,BitOR ($SS_CENTERIMAGE,$SS_CENTER))
            GUICtrlCreateLabel ('PatrolBoat :',10,($l_size*10)+(5*$l_size),$l_size*5,$l_size,BitOR ($SS_CENTERIMAGE,$SS_CENTER))

            GUICtrlCreateLabel ('',10+($l_size*5),($l_size*10)+$l_size,$l_size*5,$l_size, $WS_BORDER)
            GUICtrlCreateLabel ('',10+($l_size*5),($l_size*10)+(2*$l_size),$l_size*4,$l_size, $WS_BORDER)
            GUICtrlCreateLabel ('',10+($l_size*5),($l_size*10)+(3*$l_size),$l_size*3,$l_size, $WS_BORDER)
            GUICtrlCreateLabel ('',10+($l_size*5),($l_size*10)+(4*$l_size),$l_size*2,$l_size, $WS_BORDER)
            GUICtrlCreateLabel ('',10+($l_size*5),($l_size*10)+(5*$l_size),$l_size*1,$l_size, $WS_BORDER)



            GUICtrlCreateRadio ('Horizontal Positioning',20+($l_size*10),($l_size*10)+(1*$l_size),$l_size*5,$l_size)
                GUICtrlSetState(-1, $GUI_CHECKED)
                GUICtrlSetOnEvent (-1,'ChangeAlignment')
            GUICtrlCreateRadio ('Vertical Positioning',20+($l_size*10),($l_size*10)+(2*$l_size),$l_size*5,$l_size)
                GUICtrlSetOnEvent (-1,'ChangeAlignment')


            $AI_HitsTaken_Label = GUICtrlCreateLabel  ('',20+($l_size*10),($l_size*10)+(4*$l_size),$l_size*10,$l_size)
            $Player_HitsTaken_Label = GUICtrlCreateLabel( '',20+($l_size*10),($l_size*10)+(5*$l_size),$l_size*10,$l_size)

    GUISetOnEvent (-3,'QUIT',$Player_gui_parent)
    GUISetState ()
    MsgBox (0,'BATTLESHIPS','Hello.' & @CRLF & 'Before We Can Start, You Must Position Your Ships On Your Left Grid.','',WinGetHandle ('[active]'))


    $Player_gui_grid_ships[0][0] = GUICreate ('Player:Ships',$l_size*10,$l_size*10,10,10,$WS_POPUPWINDOW,$WS_EX_MDICHILD,$Player_gui_parent)
        For $y = 1 To 10
            For $x = 1 To 10
                $AI_grid_ships[$y][$x] = 0
                $Player_gui_grid_ships[$y][$x] = GUICtrlCreateLabel ('',(($x-1)*$l_size),(($y-1)*$l_size),$l_size,$l_size,BitOR ($SS_CENTERIMAGE,$SS_CENTER,$WS_BORDER))
                GUICtrlSetBkColor ($Player_gui_grid_ships[$y][$x],0xABCDEF)
                GUICtrlSetOnEvent ($Player_gui_grid_ships[$y][$x],'PositionShip')
                GUICtrlSetCursor ($Player_gui_grid_ships[$y][$x],0)
            Next
        Next
    GUISetState ()




While $CurrentShip_to_be_Set >= 1
    Sleep (100)
WEnd


    $Player_gui_grid_explosives[0][0] = GUICreate ('Player:Explosives',$l_size*10,$l_size*10,($l_size*10)+20,10,$WS_POPUPWINDOW,$WS_EX_MDICHILD,$Player_gui_parent)
        For $y = 1 To 10
            For $x = 1 To 10
                $Player_gui_grid_explosives[$y][$x] = GUICtrlCreateLabel ($y&':'&$x,($x-1) * $l_size,($y - 1) * $l_size,$l_size,$l_size,BitOR ($SS_CENTERIMAGE,$SS_CENTER,$WS_BORDER))
                GUICtrlSetBkColor ($Player_gui_grid_explosives[$y][$x],0xABCDEF)
                GUICtrlSetOnEvent ($Player_gui_grid_explosives[$y][$x],'Attack')
                GUICtrlSetCursor ($Player_gui_grid_explosives[$y][$x],3)
            Next
        Next
    GUISetState ()


    For $N = 5 To 1 Step -1
        While 1
            $error = 0
            $x = Random(1,10,1)
            $y = Random (1,10,1)
            $AI_Alignment = Random (0,1,1)
            If $AI_grid_ships[$y][$x] = 0 Then
                If $AI_Alignment = 0 Then ;VERTICAL
                    If ($y-1)+$N <= 10 Then

                        For $U = 0 To $N-1
                            If $AI_grid_ships[$y+$U][$x] = 1 Then $error = 1
                        Next
                        If $error <> 1 Then
                            For $U = 0 To $N-1
                                $AI_grid_ships[$y+$U][$x] = 1
                            Next
                            ExitLoop
                        EndIf
                    EndIf
                ElseIf $AI_Alignment = 1 Then ;HORIZONTAL
                    If ($x-1)+$N <= 10 Then

                        For $U = 0 To $N-1
                            If $AI_grid_ships[$y][$x+$U] = 1 Then $error = 1
                        Next
                        If $error <> 1 Then
                            For $U = 0 To $N-1
                                $AI_grid_ships[$y][$x+$U] = 1
                            Next
                            ExitLoop
                        EndIf
                    EndIf
                EndIf
            EndIf
        WEnd
    Next
EndFunc
Func ChangeAlignment ()
    If $Alignment = 0 Then ;if vertical then make horizontal
        $Alignment = 1
        Return
    ElseIf $Alignment = 1 Then ;if horizontal then make vertical
        $Alignment = 0
        Return
    EndIf
EndFunc
Func CheckVertical ($y,$x,$length)
    Local $Count
    If ($y-1)+$length <= 10  Then
        For $Count = 1 To $length
            If GUICtrlRead ($Player_gui_grid_ships[($y-1)+$Count][$x]) == ' ' Then Return -1
        Next
        Return 1
    EndIf
EndFunc
Func CheckHorizontal ($y,$x,$length)
    Local $Count
    If ($x-1)+$length <= 10 Then
        For $Count = 1 To $length
            If GUICtrlRead ($Player_gui_grid_ships[$y][($x-1)+$Count]) == ' ' Then Return -1
        Next
        Return 1
    EndIf
EndFunc
Func Attack ()
    Local $y, $x, $Count
    For $y = 1 To 10
        For $x = 1 To 10
            If @GUI_CtrlId = $Player_gui_grid_explosives[$y][$x] Then
                If GUICtrlRead ($Player_gui_grid_explosives[$y][$x]) <> ' ' Then
                    If $AI_grid_ships[$y][$x] = 1 Then
                        GUICtrlSetOnEvent (@GUI_CtrlId,'')
                        GUICtrlSetBkColor (@GUI_CtrlId,0xFF0000)
                        $AI_HitsTaken += 1
                    Else
                        GUICtrlSetBkColor (@GUI_CtrlId,0xFFFFFF)
                    EndIf
                    GUICtrlSetOnEvent (@GUI_CtrlId,'')
                    GUICtrlSetData (@GUI_CtrlId, ' ')
                    GUICtrlSetCursor (@GUI_CtrlId,7)
                    AI_Attack ()
                EndIf
            EndIf
        Next
    Next
EndFunc
Func AI_Attack ()
    Local $x, $y, $status = 0
    While $status = 0
        $x = Random (1,10,1)
        $y = Random (1,10,1)
        If GUICtrlRead ($Player_gui_grid_ships[$y][$x]) <> ' ' Then
            If  GUICtrlRead ($Player_gui_grid_ships[$y][$x]) <> '' Then
                GUICtrlSetBkColor ($Player_gui_grid_ships[$y][$x],0xFF0000)
                $Player_HitsTaken += 1
                $AI_last_hit_on_Player = $y&':'&$x
                Return
            Else
                GUICtrlSetBkColor ($Player_gui_grid_ships[$y][$x],0xFFFFFF)
                Return
            EndIf
        EndIf
    WEnd
EndFunc
Func PositionShip ()
    Local $y, $x, $Count
    For $y = 1 To 10
        For $x = 1 To 10
            If @GUI_CtrlId = $Player_gui_grid_ships[$y][$x] Then
                If $CurrentShip_to_be_Set < 1 Then
                    For $y = 1 To 10
                        For $x = 1 To 10
                            GUICtrlSetOnEvent ( $Player_gui_grid_ships[$y][$x],'')
                            GUICtrlSetCursor ($Player_gui_grid_ships[$y][$x],2)
                        Next
                    Next
                    Return
                Else
                    If $Alignment = 0 Then ;VERTICAL PLACEMENT
                        If CheckVertical ($y,$x,$CurrentShip_to_be_Set) <> -1 Then
                            If $y <= (10-($CurrentShip_to_be_Set-1)) Then
                                For $Count = 0 To $CurrentShip_to_be_Set-1
                                    GUICtrlSetData ($Player_gui_grid_ships[$y+$Count][$x],$CurrentShip_to_be_Set)
                                    GUICtrlSetBkColor ($Player_gui_grid_ships[$y+$Count][$x],0x0)
                                    GUICtrlSetOnEvent ( $Player_gui_grid_ships[$y+$Count][$x],'')
                                Next
                                $CurrentShip_to_be_Set = ($CurrentShip_to_be_Set - 1)
                                Return
                            EndIf
                        EndIf
                    ElseIf $Alignment = 1 Then ;HORIZONTAL PLACEMENT
                        If CheckHorizontal ($y,$x,$CurrentShip_to_be_Set) <> -1 Then
                            If $x <= (10-($CurrentShip_to_be_Set-1)) Then
                                For $Count = 0 To $CurrentShip_to_be_Set-1
                                    GUICtrlSetData ($Player_gui_grid_ships[$y][$x+$Count],$CurrentShip_to_be_Set)
                                    GUICtrlSetBkColor ($Player_gui_grid_ships[$y][$x+$Count],0x0)
                                    GUICtrlSetOnEvent ( $Player_gui_grid_ships[$y][$x+$Count],'')
                                Next
                                $CurrentShip_to_be_Set = ($CurrentShip_to_be_Set - 1)
                                Return
                            EndIf
                        EndIf
                    EndIf
                EndIf
            EndIf
        Next
    Next
EndFunc
Func QUIT ()
    Exit
EndFunc

what else could be improved? what do you guys think?

Edited by CodyBarrett
Link to comment
Share on other sites

That's quite good. I have a few suggestions though. All the ships are arranged horizontally, and it's too easy to win.

Edit

Oops, ignore what I just said. I didn't notice you had already said that. :x

It has no memory of the fields it has already fired upon.

I was thinking of making a version of this myself previouisly. It's a great game.

Edited by czardas
Link to comment
Share on other sites

i believe (unless i just made a mental note and forgot to do it) that i added this

if the label reads 5-1 then its a ship, and if its ' ' its a miss, and if its '' then its blank. i believe i check if its a blank string or a number for every attack so it picks a spot that hasn't gotten a miss already.

Is that what you were talking about?

Link to comment
Share on other sites

oooooh alrighty, i'll look into that:

---i'll record the position for every enemy strike

---fix the max positioning for horizontal movement

something i haven't noticed. thanks guys!

Link to comment
Share on other sites

Here's some code that Manadar wrote. It randomly arranges ships in a grid. Be careful not to place too many ships in the grid or it may lock up.

#include <Array.au3>

Local $grid[10][10]

; _PlaceShip in $grid with a ship length of 5
_PlaceShip($grid, 5, 'A') ; Aircraft carrier
_PlaceShips($grid, 2, 4, 'B') ; battleship
_PlaceShips($grid, 4, 3, 'D') ; destroyer
_PlaceShip($grid, 3, 'S') ; submarine
_PlaceShips($grid, 4, 2, 'P') ; patrol boat

_ArrayDisplay($grid)

; Places a number of ships with set length on the grid
Func _PlaceShips(ByRef $grid, $number, $length, $identification)
    For $i = 1 To $number
        _PlaceShip($grid, $length, $identification)
    Next
EndFunc

Func _PlaceShip(ByRef $grid, $length, $identification)
    $length = $length - 1 ; Don't know why this is needed, but it was making everything 1 too long. This is a simple fix
    $maxX = UBound($grid, 1)-1
    $maxY = UBound($grid, 2)-1

    While True
        ; Find any random start position to place the ship
        $startX = Random(0, $maxX, 1)
        $startY = Random(0, $maxY, 1)
        $endX = $startX
        $endY = $startY
        $valid = False

        ; Check if that random position is taken or not
        If Not _IsPositionTaken($grid, $startX, $startY) Then
            ; If the position is not taken, we create a random direction and start checking in that direction if those spots are taken
            $direction = Random(0, 1, 1)
            Switch $direction
            Case 0 ; Horizontal
                $isEmpty = _CheckHorizontal($grid, $startX, $startY, $length)
                If $isEmpty Then
                    $endX = $startX + $length
                    ExitLoop
                EndIf
            Case 1 ; Vertical
                $isEmpty = _CheckVertical($grid, $startX, $startY, $length)
                $endY = $startY + $length
                If $isEmpty Then
                    ExitLoop
                EndIf
            EndSwitch
        EndIf
    WEnd

    ; Now we place the boat, cause we know where it goes
    ; The variation in X or Y could be 1 (creating a line)
    For $x = $startX To $endX
        For $y = $startY To $endY
            $grid[$x][$y] = $identification
        Next
    Next
EndFunc

Func _CheckHorizontal(ByRef $grid, $startX, $startY, $length)
    For $x = $startX To $startX + $length
        If _IsPositionTaken($grid, $x, $startY) Then
            Return False
        EndIf
    Next
    Return True
EndFunc

Func _CheckVertical(ByRef $grid, $startX, $startY, $length)
    For $y = $startY To $startY + $length
        If _IsPositionTaken($grid, $startX, $y) Then
            Return False
        EndIf
    Next
    Return True
EndFunc

Func _IsPositionTaken($grid, $x, $y)
    If $x > UBound($grid, 1)-1 Then
        Return True
    EndIf
    If $y > UBound($grid, 2)-1 Then
        Return True
    EndIf
    Return $grid[$x][$y] <> ""
EndFunc

I hope it comes in useful.

Edited by czardas
Link to comment
Share on other sites

NEW VERSION UPDATED AT THE TOP!

i fixed a few things, like how it wouldn't let you position a ship on the rightmost part of the grid. now you can, and i've added vertical placements also!

Link to comment
Share on other sites

Very nice so far.

You have it available so why not:

A running score PC vs Me?

Display the final scores in the final message.

Dont delete the Gui immediately after a win. Only after the final message.

I like to stare at the final outcome.

DONE... updated at the top.

Wonderfull job,

Just one thing , i should like to see the ships not as a black square but a picture of the ship see by top !

i'll work on that.. might take a while. :x i'm horrible with graphics.

Link to comment
Share on other sites

Pretty fun :x

Do you remember the original Battleship? You had holes in the top to place the pegs when a ship was destroyed so you could keep track of how many enemy boats were killed...

How about something like that so you know when an enemy boat is sunk?

010101000110100001101001011100110010000001101001011100110010000

001101101011110010010000001110011011010010110011100100001

My Android cat and mouse game
https://play.google.com/store/apps/details?id=com.KaosVisions.WhiskersNSqueek

We're gonna need another Timmy!

Link to comment
Share on other sites

  • 2 months later...

how to play it?

#1 - it should prompt you with a MSGBOX.

#2 - you must position your ships on the left grid.

#3 - HORIZONTAL positioning / VERTICAL positioning are available Via the radio buttons below the grids.

#4 - click on the left grid to place your ships.

#5 - once all ships are placed the Computer will randomly place It's ships on the right grid.

#6 - OPEN FIRE! destroy all the Computers Ships by clicking on the right grid.

Link to comment
Share on other sites

CodyBarret,

That's pretty cool. I did a BattleShips games in Visual Pinball a few years ago but didn't release it as it had AI errors. I see your AI is a little dumb. I found it quite difficult to implement an intelligent attack on the player based on established hits. It's relatively easy to think thru, but did my head in completely at the time. I was working on 3-4 big projects and just got burned out.

Mine had a teal green background with really rough shapes for the ships etc. I'll attach a graphic that I used at the time. Edit... I've attached a pic of the game in action. As the engine has changed somewhat some of the graphical elements are out of whack. To put you in the picture, VP was developed years ago to 'recreate' classic pinball tables. It was mod'ed to allow initially one of a row of graphics to be displayed then later one of a grid of graphics. This opened it to my uncreative talents to create a few games that were not pinball related. My Video Poker came up very well with help from a graphically adept colleague. Sorry I digress. It may not be obvious from the attached graphics but the game automatically created a layout for the player which could be rejected and an alternate generated.

BTW, I played only one game but the representation of the various ships that you pick to put on the grid seem to bear little or no resemblance to the size of the ship actually placed on the grid.

Good work. Keep it up.

Regards,

4Eyes

BSSegments3WithGrid.bmp

post-47302-0-48783100-1298945015_thumb.j

Link to comment
Share on other sites

yeah, i had difficulty with the x3 size ship (sub) and (destroyer) i believe. i could get two different x3 size ships but couldn't differentiate between sub or destroyer, they were both x3 size.

Link to comment
Share on other sites

I'm sure i could make a lot more improvements on it, i just don't have time.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...