Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #NoEnv
- #SingleInstance, Force
- #Persistent
- Process, Priority,, High
- SetBatchLines, -1
- ListLines, Off
- SetWinDelay, -1
- /*
- Options : an array of
- - an array of ships length
- - number of rows and columns of the grid
- - the size of the cells (pixels)
- */
- small := [[2, 2, 2, 3, 3, 4], 8, 40]
- medium := [[2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5], 15, 30]
- large := [[2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7], 25, 18]
- Battleship := New Battleship(small)
- OnMessage(0x200,"OnMouseMove")
- Return
- OnMouseMove() {
- Battleship.Hover(A_GuiControl)
- }
- BattleshipGuiClose:
- ExitApp
- class Battleship {
- __New(options) {
- this.ships := options[1]
- this.grid := options[2]
- this.size := options[3]
- this.CurrentHover := 0
- this.colors := {background: "969696", water:"122A5A", hover:"617298", ship:"135A12", hit:"6C1E15", miss:"414141", sank:"171A1F"}
- this.human := new Player(this.ships, this.grid, "human", "computer")
- this.computer := new Player(this.ships, this.grid, "computer", "human")
- this.squares := {}
- this.CreateGui()
- for i, j in this.human.grid {
- for k, l in j {
- if l.ship
- this.ChangeColor("h" "X" i "Y" k, this.colors.ship)
- }
- }
- this.turn := "human"
- this.winner := 0
- }
- CreateGui() {
- Gui Battleship: Color, % this.colors.background
- Gui Battleship: Show, % "w" this.size * this.grid " h" (this.size * this.grid * 2) + 30, Battleship
- this.CreateGrid("c", 0)
- this.CreateGrid("h", (this.grid * this.size) + 30)
- }
- Hover(btn) {
- btn := StrReplace(btn, "b")
- coord := StrSplit(btn, ["X","Y"])
- x := coord[2]
- y := coord[3]
- NoHover := 0
- if this.human.Egrid[x][y].revealed
- NoHover := 1
- if (!btn OR (SubStr(btn, 1, 1) != "c") OR NoHover) AND this.CurrentHover {
- this.ChangeColor(this.CurrentHover, this.colors.water)
- this.CurrentHover := 0
- }
- if (btn != 0) AND (SubStr(btn, 1, 1) = "c") AND (btn != this.CurrentHover) AND !NoHover {
- this.ChangeColor(this.CurrentHover, this.colors.water)
- this.CurrentHover := btn
- this.ChangeColor(this.CurrentHover, this.colors.hover)
- }
- }
- CreateGrid(player, offset) {
- Global
- if (offset = 0)
- Gui Battleship: Add, Text, % "x10 y" (this.grid * this.size) + 7 " w" (this.grid * this.size) - 10 " h" 30 - 7 " vInfoText",
- Loop, % this.grid
- {
- x := A_Index
- Loop, % this.grid
- {
- y := A_Index
- Gui Battleship: Add, Progress, % "w" this.size - 2 " h" this.size - 2 " x" ((x - 1) * this.size) + 1 " y" ((y - 1) * this.size) + offset + 1 " Background" this.colors.water " Disabled -E0x0200 v" player "X" x "Y" y
- Gui Battleship: Add, Text, % "w" this.size - 2 " h" this.size - 2 " x" ((x - 1) * this.size) + 1 " y" ((y - 1) * this.size) + offset + 1 " BackgroundTrans v" player "bX" x "Y" y
- BindBtn := ObjBindMethod(this, "DropBomb", {p:player,x:x,y:y})
- GuiControl Battleship: +g, % player "bX" x "Y" y, % BindBtn
- }
- }
- }
- DropBomb(d) {
- if this.winner
- Return
- if (d.p = "c") {
- receiver := "computer"
- attacker := "human"
- }
- else {
- receiver := "human"
- attacker := "computer"
- }
- if this[attacker].Click(d.x, d.y) {
- hit := this[receiver].TakeHit(d.x, d.y)
- this[attacker].GiveHit(d.x, d.y, hit.shipID)
- if (hit.shipL < 0) {
- this.CurrentHover := 0
- this.ChangeColor(SubStr(receiver, 1, 1) "X" d.x "Y" d.y, this.colors.miss)
- }
- else if (hit.shipL = 0) {
- this.CurrentHover := 0
- this.Sink(attacker, receiver, hit.shipID)
- }
- else if (hit.shipL >= 0) {
- this.CurrentHover := 0
- this.ChangeColor(SubStr(receiver, 1, 1) "X" d.x "Y" d.y, this.colors.hit)
- }
- if (this.turn = "computer") AND (hit.shipL >= 0)
- this.computer.MadeDamage(d, hit)
- if this.winner {
- this.turn := 0
- Return
- }
- this.ChangeTurn()
- if (this.turn = "computer")
- this.DropBomb(this.computer.Play())
- }
- }
- Sink(attacker, receiver, shipID) {
- parts := this[receiver].GetParts(shipID)
- this[attacker].Sink(parts)
- for i, j in parts {
- this.ChangeColor(SubStr(receiver, 1, 1) "X" j.x "Y" j.y, this.colors.sank)
- }
- if (this[receiver].GetTotalL() = 0) {
- this.SetWinner(attacker)
- }
- }
- SetWinner(player) {
- Global
- phrases := {}
- phrases["computer"] := ["You lost again.","You should stick to tic-tac-toe.","Git Gud."]
- phrases["human"] := ["I let you win.","90% luck.","No life."]
- this.winner := player
- Random, p, 1, 3
- text := phrases[this.winner][p]
- GuiControl Battleship: Text, InfoText, % text
- if (this.winner = "computer") {
- for i, j in this.computer.grid {
- for k, l in j {
- if l.ship {
- if !this.human.Egrid[i][k].hit
- this.ChangeColor("c" "X" i "Y" k, this.colors.ship)
- this.human.Egrid[i][k].revealed := 1
- }
- }
- }
- }
- }
- ChangeTurn() {
- if (this.turn = "human")
- this.turn := "computer"
- else
- this.turn := "human"
- }
- ChangeColor(btn, c) {
- GuiControl Battleship: +Background%c%, % btn
- }
- }
- class Player {
- __New(ships, grid, player, enemy) {
- this.name := {long:player,short:SubStr(player,1,1)}
- this.enemy := {long:enemy,short:SubStr(enemy,1,1)}
- this.ships := []
- this.ToDestroy := []
- for i, l in ships {
- this.ships.Push({l:l,parts:[]})
- }
- this.grid := []
- this.Egrid := []
- this.targets := {}
- Random, fl, 0, 1
- xt := 0
- Loop, % grid
- {
- xt += 1
- yt := 0
- row := []
- Erow := []
- Loop, % grid
- {
- yt += 1
- row.Push({ship:0,avaible:1,shipID:0})
- Erow.Push({hit:0,ship:0,revealed:0,sank:0,nothing:0})
- if Mod(fl + xt + yt, 2)
- this.targets["X" xt "Y" yt] := {x:xt,y:yt}
- }
- this.grid.Push(row)
- this.Egrid.Push(Erow)
- }
- validGrid := 0
- while (validGrid = 0)
- {
- validGrid := this.RandomShips(this.grid, this.ships)
- if (A_Index > 20)
- Break
- }
- this.grid := validGrid
- for i, j in this.grid {
- for k, l in j {
- if l.ship {
- this.ships[l.shipID].parts.Push({x:i,y:k})
- }
- }
- }
- }
- Play() {
- if (this.ToDestroy.Length() > 0) {
- if (this.ToDestroy.Length() = 1) {
- candidates := []
- dirs := [["x","y"],["y","x"]]
- d := [1,-1]
- for i, dir in dirs[1] {
- for k, l in d {
- c%dir% := this.ToDestroy[1][dir] + l
- odir := dirs[2][i]
- c%odir% := this.ToDestroy[1][odir]
- if (this.Egrid[cx][cy].hit = "0") AND (this.Egrid[cx][cy].nothing = "0") AND (this.Egrid[cx][cy].revealed = "0") AND (cx > 0) AND (cy > 0) AND (cx <= this.Egrid.Length()) AND (cy <= this.Egrid.Length())
- candidates.Push({x:cx,y:cy})
- }
- }
- }
- else if (this.ToDestroy.Length() > 1) {
- candidates := []
- if (this.ToDestroy[1].x = this.ToDestroy[2].x) {
- dir := "y"
- odir := "x"
- cx := this.ToDestroy[1].x
- }
- else {
- dir := "x"
- odir := "y"
- cy := this.ToDestroy[1].y
- }
- max := 0
- min := this.Egrid.Length() + 1
- for i, j in this.ToDestroy {
- if (j[dir] > max)
- max := j[dir]
- if (j[dir] < min)
- min := j[dir]
- }
- min -= 1
- max += 1
- ds := [min,max]
- for i, d in ds {
- c%dir% := d
- if (this.Egrid[cx][cy].hit = "0") AND (this.Egrid[cx][cy].nothing = "0") AND (this.Egrid[cx][cy].revealed = "0") AND (cx > 0) AND (cy > 0) AND (cx <= this.Egrid.Length()) AND (cy <= this.Egrid.Length())
- candidates.Push({x:cx,y:cy})
- }
- }
- Random, rC, 1, candidates.Length()
- Return {p:"h",x:candidates[rC].x,y:candidates[rC].y}
- }
- Random, rID, 1, this.targets.Count()
- a := 1
- for i, j in this.targets {
- if (a = rID) {
- tID := i
- Break
- }
- a += 1
- }
- targ := this.targets.Delete(tID)
- Return {p:"h",x:targ.x,y:targ.y}
- }
- MadeDamage(d, hit) {
- this.ToDestroy.Push({x:d.x,y:d.y})
- if (hit.shipL = 0) {
- candidates := []
- if (this.ToDestroy[1].x = this.ToDestroy[2].x) {
- dir := "y"
- odir := "x"
- cx := this.ToDestroy[1].x
- }
- else {
- dir := "x"
- odir := "y"
- cy := this.ToDestroy[1].y
- }
- max := 0
- min := this.Egrid.Length() + 1
- for i, j in this.ToDestroy {
- if (j[dir] > max)
- max := j[dir]
- if (j[dir] < min)
- min := j[dir]
- }
- min -= 1
- max += 1
- ds := [min,max]
- for i, d in ds {
- c%dir% := d
- candidates.Push({x:cx,y:cy})
- this.targets.Delete("X" cx "Y" cy)
- }
- this.ToDestroy := []
- }
- }
- Click(x, y) {
- if !this.Egrid[x][y].revealed
- Return 1
- Return 0
- }
- TakeHit(x, y) {
- if this.grid[x][y].ship
- this.ships[this.grid[x][y].shipID].l -= 1
- if (this.ships[this.grid[x][y].shipID].l >= 0)
- shipL := this.ships[this.grid[x][y].shipID].l
- else
- shipL := -1
- return {shipID:this.grid[x][y].shipID,shipL:shipL}
- }
- GiveHit(x, y, shipID) {
- this.Egrid[x][y].revealed := 1
- this.Egrid[x][y].hit := 1
- this.targets.Delete("X" x "Y" y)
- if (shipID > 0)
- {
- this.Egrid[x][y].ship := 1
- this.Egrid[x-1][y-1].nothing := 1
- this.Egrid[x+1][y-1].nothing := 1
- this.Egrid[x-1][y+1].nothing := 1
- this.Egrid[x+1][y+1].nothing := 1
- this.targets.Delete("X" x-1 "Y" y-1)
- this.targets.Delete("X" x+1 "Y" y-1)
- this.targets.Delete("X" x-1 "Y" y+1)
- this.targets.Delete("X" x+1 "Y" y+1)
- }
- }
- Sink(parts) {
- for i, j in parts {
- this.Egrid[j.x][j.y].sank := 1
- }
- }
- GetTotalL() {
- tL := 0
- for i, j in this.ships {
- tL += j.l
- }
- Return tL
- }
- GetParts(shipID) {
- Return this.ships[shipID].parts
- }
- RandomShips(grid, ships) {
- tships := this.ObjFullyClone(ships)
- Tlen := ships.Length()
- if (ships.Length() < 1)
- Return grid
- ship := tships.Pop()
- Loop, 5
- {
- tgrid := this.ObjFullyClone(grid)
- Random, x, 1, % grid.Length()
- Random, y, 1, % grid.Length()
- Random, o, 0, 1
- tgrid := this.PlaceShip(tgrid, ship, x, y, o, Tlen)
- if (tgrid != 0) {
- Return this.RandomShips(tgrid, tships)
- }
- }
- Return 0
- }
- PlaceShip(grid, ship, x, y, o, Tlen) {
- Loop, % ship.l
- {
- if !grid[x][y].avaible
- Return 0
- else
- grid := this.PlacePart(grid, x, y, o, A_Index, ship.l, Tlen)
- if o
- x += 1
- else
- y += 1
- }
- Return grid
- }
- PlacePart(grid, x, y, o, ind, len, Tlen) {
- grid[x][y].avaible := 0
- grid[x][y].ship := 1
- grid[x][y].shipID := Tlen
- xs := []
- if x > 1
- xs.Push(x-1)
- if x < grid.Length()
- xs.Push(x+1)
- ys := []
- if y > 1
- ys.Push(y-1)
- if y < grid.Length()
- ys.Push(y+1)
- for i, j in xs {
- for k, l in ys {
- grid[j][l].avaible := 0
- }
- }
- if (ind = 1) {
- if o AND (x > 1)
- grid[x - 1][y].avaible := 0
- if !o AND (y > 1)
- grid[x][y - 1].avaible := 0
- }
- if (ind = len) {
- if o AND (x < grid.Length())
- grid[x + 1][y].avaible := 0
- if !o AND (y < grid.Length())
- grid[x][y + 1].avaible := 0
- }
- Return grid
- }
- ObjFullyClone(obj) {
- nobj := obj.Clone()
- for k,v in nobj
- if IsObject(v)
- nobj[k] := this.ObjFullyClone(v)
- return nobj
- }
- }
Add Comment
Please, Sign In to add comment