]> Skullheadx's Git Forge - monopoly-web.git/commitdiff
buy properties
authorSkullheadx <admonty1@protonmail.com>
Mon, 8 Jun 2026 23:20:10 +0000 (19:20 -0400)
committerSkullheadx <admonty1@protonmail.com>
Mon, 8 Jun 2026 23:20:10 +0000 (19:20 -0400)
game/game.go
public/index.html
public/index.js

index 3fbf01b0f24b1446c0f0eb744160959e82cfaaca..862d00b9684b440182cdbc192f0b8ceb47973746 100644 (file)
@@ -70,6 +70,8 @@ func NewMonopolyServer() *MonopolyServer {
        ms.serveMux.HandleFunc("/subscribe", ms.subscribeHandler)
        ms.serveMux.HandleFunc("/start", ms.startHandler)
        ms.serveMux.HandleFunc("/roll", ms.rollHandler)
+       ms.serveMux.HandleFunc("/buy", ms.buyHandler)
+       // ms.serveMux.HandleFunc("/auction", ms.auctionHandler)
 
        return ms
 }
@@ -180,11 +182,59 @@ func (ms *MonopolyServer) startHandler(w http.ResponseWriter, r *http.Request) {
                return
        }
 
+       if ms.gameCtx != nil {
+               http.Error(w, http.StatusText(http.StatusConflict), http.StatusConflict)
+               return
+       }
+
        ms.start()
 
        w.WriteHeader(http.StatusAccepted)
 }
 
+func (ms *MonopolyServer) buyHandler(w http.ResponseWriter, r *http.Request) {
+       if r.Method != "POST" {
+               http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
+               return
+       }
+
+       cookie, err := r.Cookie("user")
+       if err != nil {
+               if err == http.ErrNoCookie {
+                       http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+                       return
+               }
+
+               http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
+               return
+       }
+
+       userUUID := cookie.Value
+
+       _, ok := ms.users[userUUID]
+       if !ok {
+               http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
+               return
+       }
+
+       if ms.gameCtx == nil {
+               http.Error(w, "Game has not started yet", http.StatusConflict)
+               return
+       }
+       if !ms.gameCtx.ValidateCanBuy(userUUID) {
+               http.Error(w, "Not your turn", http.StatusForbidden)
+               return
+       }
+       ms.buy()
+       w.WriteHeader(http.StatusOK)
+}
+
+func (ms *MonopolyServer) buy() {
+       ms.gameCtx.Buy()
+
+       ms.gameCtx.logGameCtx()
+}
+
 func (ms *MonopolyServer) rollHandler(w http.ResponseWriter, r *http.Request) {
        if r.Method != "POST" {
                http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
@@ -454,6 +504,16 @@ func (ctx *Context) ValidateIsTurn(userUUID string) bool {
        return false
 }
 
+func (ctx *Context) ValidateCanBuy(userUUID string) bool {
+       player := ctx.Players.Alive[ctx.Turn.Current.Index()]
+       prop := ColorProperties[BoardSpaces[player.CurrentSpaceID.Index()].SubIndexID]
+
+       if ctx.ValidateIsTurn(userUUID) && ctx.EventPeek() == EventLandUnowned && player.Money >= prop.Price {
+               return true
+       }
+       return false
+}
+
 func (ctx *Context) ValidateCanRoll(userUUID string) bool {
        if ctx.ValidateIsTurn(userUUID) && (ctx.EventPeek() == EventRollDice || ctx.EventPeek() == EventJail) {
                return true
@@ -523,6 +583,22 @@ func (ctx *Context) RollDice() {
        ctx.Turn.MoveQueue = append(ctx.Turn.MoveQueue, diceRoll1+diceRoll2)
 }
 
+func (ctx *Context) Buy() {
+       ctx.EventPop()
+
+       playerID := ctx.Turn.Current
+       player := ctx.Players.Alive[playerID.Index()]
+       prop := ColorProperties[BoardSpaces[player.CurrentSpaceID.Index()].SubIndexID]
+
+       for i, p := range ctx.Properties.Owners {
+               if p.SpaceID == player.CurrentSpaceID {
+                       ctx.Properties.Owners[i].OwnerID = playerID
+               }
+       }
+
+       ctx.AdjustPlayerMoney(playerID, -prop.Price)
+}
+
 func (ctx *Context) EndTurn() {
        ctx.EventPop()
        nextTurnPlayerID := PlayerID{ID: (ctx.Turn.Current.ID + 1) % int32(len(ctx.Players.Alive))}
index 3dc8e76c662e0ec6c76a02e06fa0c7aed4d7e236..b7d25794f6934404159e1bb065fe24e5323a7ce7 100644 (file)
@@ -20,6 +20,7 @@
 
                        <button id="start" type="button">Start</button>
                        <button id="roll" type="button">Roll</button>
+                       <button id="buy" type="button">Buy</button>
                </div>
                <script type="text/javascript" src="/index.js"></script>
        </body>
index e965ea7df589fc9725b7e9c099f82c7e4c644213..83c1844d6e9aa6732c1b963242061321fb727a47 100644 (file)
                         const resp = await fetch('/loggedin', {
                                 method: 'GET'
                         })
+                        if (resp.status === 404) {
+                                console.warn("User not logged in.");
+                                return;
+                        }
+
                         if (resp.status !== 200) {
                                 throw new Error(`Unexpected HTTP Status ${resp.status} ${resp.statusText}`)
                         }
@@ -44,6 +49,7 @@
         const loginInput = document.getElementById('login-input')
         const startButton = document.getElementById('start')
         const rollButton = document.getElementById('roll')
+        const buyButton = document.getElementById('buy')
 
         function appendGameLog(text) {
                 const p = document.createElement('p')
                 }
         })
 
+        buyButton.addEventListener('click', async () => {
+                try {
+                        const resp = await fetch('/buy', {
+                                method: 'POST',
+                        })
+                        if (resp.status !== 200) {
+                                throw new Error(`Unexpected HTTP Status ${resp.status} ${resp.statusText} ${resp.message}`)
+                        }
+                } catch (err) {
+                        console.error(`Start failed: ${err.message}`)
+                }
+        })
+
 })()