Skip to content

Commit

Permalink
Merge pull request #39 from Longwater1234/dev
Browse files Browse the repository at this point in the history
More enhancement for the code
  • Loading branch information
Longwater1234 authored Nov 30, 2024
2 parents 558d822 + 715881a commit efe2b1b
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 55 deletions.
46 changes: 23 additions & 23 deletions game/pieces.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"math"
)

const SIZE_CELL float32 = 75.0 //length of single square cell
const SIZE_CELL = 75.0 // length of single square cell

type Vec2 struct {
X float32 // x position
Expand All @@ -24,15 +24,15 @@ type Piece struct {
Id int32 // unique piece id
IsKing bool // whether this piece is King
Pos Vec2 // current piece position
PieceColor PieceType // either red or black
PieceColor PieceType // either RED or BLACK
}

// MoveSimple actually moves this piece diagonally to given `destPos` by 1 cell. Returns TRUE if successful
func (p *Piece) MoveSimple(destPos *Vec2) bool {
var deltaX = float64(destPos.X - p.Pos.X)
var deltaY = float64(destPos.Y - p.Pos.Y)
// MoveSimple actually moves this piece diagonally to given destination by 1 cell. Returns TRUE if successful
func (p *Piece) MoveSimple(dest *Vec2) bool {
var deltaX = float64(dest.X - p.Pos.X)
var deltaY = float64(dest.Y - p.Pos.Y)

if math.Abs(deltaX) != float64(SIZE_CELL) || math.Abs(deltaY) != float64(SIZE_CELL) {
if math.Abs(deltaX) != SIZE_CELL || math.Abs(deltaY) != SIZE_CELL {
return false
}
if p.PieceColor == Piece_Red && deltaY > 0 && !p.IsKing {
Expand All @@ -42,21 +42,21 @@ func (p *Piece) MoveSimple(destPos *Vec2) bool {
return false
}

p.Pos.X = destPos.X
p.Pos.Y = destPos.Y
if (p.PieceColor == Piece_Red && destPos.Y == 0) ||
(p.PieceColor == Piece_Black && destPos.Y == 7*SIZE_CELL) {
p.Pos.X = dest.X
p.Pos.Y = dest.Y
if (p.PieceColor == Piece_Red && dest.Y == 0) ||
(p.PieceColor == Piece_Black && dest.Y == 7*SIZE_CELL) {
p.IsKing = true
}
return true
}

// MoveCapture actually moves this piece by 2 cells diagonally to the given `destPos`. Returns TRUE if success
func (p *Piece) MoveCapture(destPos *Vec2) bool {
var deltaX = float64(destPos.X - p.Pos.X)
var deltaY = float64(destPos.Y - p.Pos.Y)
// MoveCapture (when attacking) moves this piece by 2 cells diagonally to the given `destination`. Returns TRUE if success
func (p *Piece) MoveCapture(dest *Vec2) bool {
var deltaX = float64(dest.X - p.Pos.X)
var deltaY = float64(dest.Y - p.Pos.Y)

if math.Abs(deltaX) != float64(2*SIZE_CELL) || math.Abs(deltaY) != float64(2*SIZE_CELL) {
if math.Abs(deltaX) != 2*SIZE_CELL || math.Abs(deltaY) != 2*SIZE_CELL {
return false
}
if p.PieceColor == Piece_Red && deltaY > 0 && !p.IsKing {
Expand All @@ -66,16 +66,16 @@ func (p *Piece) MoveCapture(destPos *Vec2) bool {
return false
}

p.Pos.X = destPos.X
p.Pos.Y = destPos.Y
if (p.PieceColor == Piece_Red && destPos.Y == 0) ||
(p.PieceColor == Piece_Black && destPos.Y == 7*SIZE_CELL) {
p.Pos.X = dest.X
p.Pos.Y = dest.Y
if (p.PieceColor == Piece_Red && dest.Y == 0) ||
(p.PieceColor == Piece_Black && dest.Y == 7*SIZE_CELL) {
p.IsKing = true
}
return true
}

// IsEvenCellRow determines whether given `cellIdx` is on even Row on the board
// IsEvenCellRow determines whether the CELL with given Index is on EVEN Row on the board
func IsEvenCellRow(cellIdx int32) bool {
rowNumber := 9 - (cellIdx-1)/4
return rowNumber%2 == 0
Expand All @@ -86,10 +86,10 @@ func IsAwayFromEdge(pos *Vec2) bool {
return pos.X > 0 && pos.X < 7*SIZE_CELL && pos.Y > 0 && pos.Y < 7*SIZE_CELL
}

// HasWinner determines if `p` has won the match against `opponent`, then notifies both players if TRUE.
// HasWinner returns TRUE if `p` has won the match against `opponent`, then notifies both players.
func HasWinner(p *player.Player, opponent *player.Player) bool {
if len(opponent.Pieces) == 0 {
//`opponent` has lost, `p` has won! game over
// Meaning `opponent` has lost, `p` has won! Game over
p.SendMessage(&BasePayload{
Notice: "Congrats! You won! GAME OVER",
Inner: &BasePayload_WinlosePayload{
Expand Down
10 changes: 5 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import (
"golang.org/x/net/websocket"
)

const SERVER_VERSION = "1.0.8"
const maxRequestSize int = 1 << 10 //1KB
const SERVER_VERSION = "1.0.9"
const maxRequestSize int = 1 << 10 // 1KB

var numPlayers atomic.Uint32 // total number of LIVE players
var lobby = make(chan *player.Player, 2) // waiting room for players
var lobby = make(chan *player.Player, 1) // waiting room for players

func main() {
portNum, err := strconv.Atoi(os.Getenv("PORT"))
Expand All @@ -30,13 +30,13 @@ func main() {
port := strconv.Itoa(portNum)

http.HandleFunc("/", func(writer http.ResponseWriter, r *http.Request) {
fmt.Fprintf(writer, `<p>This is a socket server. Dial ws://%s:%s/game </p>`, r.URL.Host, port)
fmt.Fprintf(writer, `<p>This is a websocket server. Dial ws://%s:%s/game </p>`, r.RemoteAddr, port)
})

http.Handle("/game", websocket.Handler(wsHandler))

go listenForJoins()
log.Println("Server listening at http://localhost:" + port)
log.Println("Server listening at http://127.0.0.1:" + port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}

Expand Down
6 changes: 3 additions & 3 deletions player/member.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ type Player struct {
Conn *websocket.Conn // client's WS connection
Name string // Name can only be RED or BLACK
Pieces []int32 // pieces IDs owned by this player. Max size 12
Dead chan<- bool // to signal this player was kicked out or left AFTER match starts
Quit <-chan bool // to detect player has quit BEFORE match starts
Dead chan<- bool // to SEND signal this player left AFTER match starts
Quit <-chan bool // to RECEIVE signal this player has quit BEFORE match starts
}

// pingCodec is used to send Ping msg to client
// pingCodec is used to send PING to client
var pingCodec = websocket.Codec{Marshal: func(v interface{}) (data []byte, payloadType byte, err error) {
return nil, websocket.PingFrame, nil
}}
Expand Down
2 changes: 1 addition & 1 deletion room/capture_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func validateCapture(captureReq *game.CapturePayload, gameMap map[int32]*game.Pi
return false
}

//check if destCell already has a Piece or not
// check whether destCell already has a Piece
destCell := captureReq.GetDestination()
_, hasValue := gameMap[destCell.GetCellIndex()]
if hasValue {
Expand Down
40 changes: 21 additions & 19 deletions room/enemy_detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

// hasExtraTargets returns TRUE if hunter's single Piece at `currCell` has EXTRA nearby targets to capture.
// This should be called only AFTER `handleCapture` by player `hunter` was successful
// This should be called only AFTER `handleCapture` by player `hunter` is TRUE
func hasExtraTargets(hunter *player.Player, currCell int32, gameMap map[int32]*game.Piece) bool {
piecePtr, exists := gameMap[currCell]
if !exists || !hunter.HasThisPiece(piecePtr.Id) {
Expand All @@ -25,7 +25,7 @@ func hasExtraTargets(hunter *player.Player, currCell int32, gameMap map[int32]*g
return false
}

// collectFrontLHS returns true ONLY IF there is an enemy on NorthWest of player `p` at currCell
// collectFrontLHS returns true ONLY IF there is an enemy on NorthWest of player `p` at `cellIdx`
func collectFrontLHS(p *player.Player, cellIdx int32, gameMap map[int32]*game.Piece) bool {
piecePtr := gameMap[cellIdx]
//check LHS (north west)
Expand All @@ -39,14 +39,15 @@ func collectFrontLHS(p *player.Player, cellIdx int32, gameMap map[int32]*game.Pi
var deltaBehindEnemy int32 = 4

var hasEnemyAhead = false
var enemyOpenBehind = false // does enemy piece have EMPTY cell behind it?
var enemyOpenBehind = false // have EMPTY cell behind enemy?

if game.IsEvenCellRow(cellIdx) {
// do swap
deltaForward, deltaBehindEnemy = deltaBehindEnemy, deltaForward
}
var mSign int32 = +1 // direction. up +1, down -1

// if player piece is Black (PLAYER 2)
// if player piece is Black (PLAYER 2), swap values
if p.Name == game.TeamColor_TEAM_BLACK.String() {
mSign = -1
deltaBehindEnemy, deltaForward = deltaForward, deltaBehindEnemy
Expand All @@ -56,13 +57,13 @@ func collectFrontLHS(p *player.Player, cellIdx int32, gameMap map[int32]*game.Pi
return false
}

pieceAhead, existFront := gameMap[cellAheadIdx] // north west (of hunter)
pieceAhead, existFront := gameMap[cellAheadIdx] // north-west (of hunter)
hasEnemyAhead = existFront && !p.HasThisPiece(pieceAhead.Id)
if existFront && !game.IsAwayFromEdge(&pieceAhead.Pos) {
return false
}

cellBehindEnemy := cellIdx + (deltaBehindEnemy * mSign) + (deltaForward * mSign) // south east (of enemy)
cellBehindEnemy := cellIdx + (deltaBehindEnemy * mSign) + (deltaForward * mSign) // south-east (of enemy)
if cellBehindEnemy > 32 || cellBehindEnemy < 1 {
return false
}
Expand All @@ -72,7 +73,7 @@ func collectFrontLHS(p *player.Player, cellIdx int32, gameMap map[int32]*game.Pi
return hasEnemyAhead && enemyOpenBehind
}

// collectFrontRHS returns true ONLY IF there is an enemy on NorthEast of this player `p` at currCell
// collectFrontRHS returns true ONLY IF there is an enemy on NorthEast of this player `p` at `cellIdx`
func collectFrontRHS(p *player.Player, cellIdx int32, gameMap map[int32]*game.Piece) bool {
piecePtr := gameMap[cellIdx]
if p.Name == game.TeamColor_TEAM_RED.String() && piecePtr.Pos.X >= 7*game.SIZE_CELL {
Expand All @@ -85,14 +86,15 @@ func collectFrontRHS(p *player.Player, cellIdx int32, gameMap map[int32]*game.Pi
var deltaBehindEnemy int32 = 3

var hasEnemyAhead = false
var enemyOpenBehind = false //is there an EMPTY cell behind enemy?
var enemyOpenBehind = false // is there an EMPTY cell behind enemy?

if game.IsEvenCellRow(cellIdx) {
//do swap
deltaBehindEnemy, deltaForward = deltaForward, deltaBehindEnemy
}
var mSign int32 = +1 // direction. up +1, down -1

// if piece is Black (PLAYER 2)
// if piece is Black (PLAYER 2), swap values
if p.Name == game.TeamColor_TEAM_BLACK.String() {
mSign = -1
deltaBehindEnemy, deltaForward = deltaForward, deltaBehindEnemy
Expand All @@ -102,13 +104,13 @@ func collectFrontRHS(p *player.Player, cellIdx int32, gameMap map[int32]*game.Pi
return false
}

pieceAhead, existFront := gameMap[cellAheadIdx] // north east
pieceAhead, existFront := gameMap[cellAheadIdx] // north-east
hasEnemyAhead = existFront && !p.HasThisPiece(pieceAhead.Id)
if existFront && !game.IsAwayFromEdge(&pieceAhead.Pos) {
return false
}

cellBehindEnemy := cellIdx + (deltaBehindEnemy * mSign) + (deltaForward * mSign) // south west (of enemy)
cellBehindEnemy := cellIdx + (deltaBehindEnemy * mSign) + (deltaForward * mSign) // south-west (of enemy)
if cellBehindEnemy > 32 || cellBehindEnemy < 1 {
return false
}
Expand Down Expand Up @@ -138,7 +140,7 @@ func collectBehindRHS(king *player.Player, cellIdx int32, gameMap map[int32]*gam
}
var mSign int32 = +1 // direction

// if player piece is Black (PLAYER 2)
// if player piece is Black (PLAYER 2), swap values
if king.Name == game.TeamColor_TEAM_BLACK.String() {
mSign = -1
deltaForward, deltaBehindEnemy = deltaBehindEnemy, deltaForward
Expand All @@ -148,13 +150,13 @@ func collectBehindRHS(king *player.Player, cellIdx int32, gameMap map[int32]*gam
return false
}

pieceAhead, existFront := gameMap[cellAheadIdx] // north west (opposite direction)
pieceAhead, existFront := gameMap[cellAheadIdx] // north-west (from behind)
hasEnemyAhead = existFront && !king.HasThisPiece(pieceAhead.Id)
if existFront && !game.IsAwayFromEdge(&pieceAhead.Pos) {
return false
}

cellBehindEnemy := cellIdx - (deltaBehindEnemy * mSign) - (deltaForward * mSign) // south east (of enemy)
cellBehindEnemy := cellIdx - (deltaBehindEnemy * mSign) - (deltaForward * mSign) // south-east (of enemy)
if cellBehindEnemy > 32 || cellBehindEnemy < 1 {
return false
}
Expand All @@ -177,14 +179,14 @@ func collectBehindLHS(king *player.Player, cellIdx int32, gameMap map[int32]*gam
var deltaBehindEnemy int32 = 4

var hasEnemyAhead = false
var enemyOpenBehind = false //is there an EMPTY cell behind enemy?
var enemyOpenBehind = false // have EMPTY cell behind enemy?

if game.IsEvenCellRow(cellIdx) {
deltaForward, deltaBehindEnemy = deltaBehindEnemy, deltaForward
}
var mSign int32 = +1 // direction
var mSign int32 = +1 // direction. +1 forward, -1 back

// if player piece is Black (PLAYER 2)
// if player piece is Black (PLAYER 2), do swap
if king.Name == game.TeamColor_TEAM_BLACK.String() {
mSign = -1
deltaForward, deltaBehindEnemy = deltaBehindEnemy, deltaForward
Expand All @@ -194,13 +196,13 @@ func collectBehindLHS(king *player.Player, cellIdx int32, gameMap map[int32]*gam
return false
}

pieceAhead, existFront := gameMap[cellAheadIdx] // north east (opposite direction)
pieceAhead, existFront := gameMap[cellAheadIdx] // north-east (from behind)
hasEnemyAhead = existFront && !king.HasThisPiece(pieceAhead.Id)
if existFront && !game.IsAwayFromEdge(&pieceAhead.Pos) {
return false
}

cellBehindEnemy := cellIdx - (deltaBehindEnemy * mSign) - (deltaForward * mSign) // south west of enemy
cellBehindEnemy := cellIdx - (deltaBehindEnemy * mSign) - (deltaForward * mSign) // south-west of enemy
if cellBehindEnemy > 32 || cellBehindEnemy < 1 {
return false
}
Expand Down
2 changes: 1 addition & 1 deletion room/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func generateGameMap(p1 *player.Player, p2 *player.Player) map[int32]*game.Piece
var iterRed = 0 //red pieces iterator
var iterBlack = 0 //black pieces iterator

// create pieces, and position them on checkerboard (in reverse)
// create pieces, and position them on checkerboard (from top -> down)
for row := 0; row < numRows; row++ {
for col := 0; col < numCols; col++ {
if (row+col)%2 != 0 {
Expand Down
4 changes: 2 additions & 2 deletions room/move_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func processMovePiece(payload *game.BasePayload, gameMap map[int32]*game.Piece,
})
return false
}
//Else, forward the "MOVE" payload to opponent
// All is OK, forward the "MOVE" payload to opponent
opponent.SendMessage(payload)
return true
}
Expand All @@ -46,7 +46,7 @@ func validateAndUpdateMap(payload *game.MovePayload, gameMap map[int32]*game.Pie
return false
}

//check if destCell already has a Piece or not
// check whether destCell already has a Piece
_, hasValue := gameMap[destination.CellIndex]
if hasValue {
return false
Expand Down
7 changes: 6 additions & 1 deletion room/room.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ func RunMatch(p1 *player.Player, p2 *player.Player, gameOver chan<- bool) {
var isPlayerRedTurn = true // Who turn is it now? RED always starts.
var gameMap = generateGameMap(p1, p2) // map of cell index --> pieces.

// free used memory after match ends
defer func() {
clear(gameMap)
}()

//START GAME MAIN LOOP
for {
if isPlayerRedTurn {
Expand Down Expand Up @@ -90,10 +95,10 @@ func RunMatch(p1 *player.Player, p2 *player.Player, gameOver chan<- bool) {
gameOver <- true
return
}
//check for extra opportunities for P1. if NONE, toggle turns
isKingNow := getKingStatusAfter(payload.GetCapturePayload(), gameMap)
currentCell := payload.GetCapturePayload().Destination.CellIndex
var needCheck bool = isKingBefore == isKingNow
// CHECK for extra opportunities for P1. if NONE, toggle turns
if needCheck && hasExtraTargets(p1, currentCell, gameMap) {
log.Println(p1.Name, " have extra targets!")
continue
Expand Down

0 comments on commit efe2b1b

Please sign in to comment.