-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
331 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package component | ||
|
||
type Room struct { | ||
Owner string `json:"owner"` | ||
PlayerX int `json:"player_x"` | ||
PlayerY int `json:"player_y"` | ||
GoalX int `json:"goal_x"` | ||
GoalY int `json:"goal_y"` | ||
} | ||
|
||
func (Room) Name() string { | ||
return "Room" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package msg | ||
|
||
type CreateRoomMsg struct{} | ||
|
||
type CreateRoomResult struct { | ||
Success bool `json:"success"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package msg | ||
|
||
type DeleteRoomMsg struct { | ||
Owner string | ||
} | ||
|
||
type DeleteRoomResult struct { | ||
Success bool `json:"success"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package msg | ||
|
||
type Direction string | ||
|
||
const ( | ||
Up Direction = "up" | ||
Down Direction = "down" | ||
Left Direction = "left" | ||
Right Direction = "right" | ||
) | ||
|
||
type MoveMsg struct { | ||
Direction Direction | ||
} | ||
|
||
type MoveMsgReply struct { | ||
Success bool `json:"success"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package query | ||
|
||
import ( | ||
"fmt" | ||
|
||
"pkg.world.dev/world-engine/cardinal/filter" | ||
"pkg.world.dev/world-engine/cardinal/types" | ||
|
||
comp "argus-exercise-1-backend/component" | ||
|
||
"pkg.world.dev/world-engine/cardinal" | ||
) | ||
|
||
type RoomStateRequest struct { | ||
Owner string | ||
} | ||
|
||
type RoomStateResponse struct { | ||
PlayerX int `json:"player_x"` | ||
PlayerY int `json:"player_y"` | ||
GoalX int `json:"goal_x"` | ||
GoalY int `json:"goal_y"` | ||
} | ||
|
||
func RoomState(world cardinal.WorldContext, req *RoomStateRequest) (*RoomStateResponse, error) { | ||
var roomState *comp.Room | ||
var err error | ||
searchErr := cardinal.NewSearch().Entity( | ||
filter.Exact(filter.Component[comp.Room]())). | ||
Each(world, func(id types.EntityID) bool { | ||
var room *comp.Room | ||
room, err = cardinal.GetComponent[comp.Room](world, id) | ||
if err != nil { | ||
return false | ||
} | ||
|
||
// Terminates the search if the room is found | ||
if room.Owner == req.Owner { | ||
roomState, err = cardinal.GetComponent[comp.Room](world, id) | ||
if err != nil { | ||
return false | ||
} | ||
return false | ||
} | ||
|
||
// Continue searching if the room is not the target room | ||
return true | ||
}) | ||
if searchErr != nil { | ||
return nil, searchErr | ||
} | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if roomState == nil { | ||
return nil, fmt.Errorf("room %s does not exist", req.Owner) | ||
} | ||
|
||
return &RoomStateResponse{ | ||
PlayerX: roomState.PlayerX, | ||
PlayerY: roomState.PlayerY, | ||
GoalX: roomState.GoalX, | ||
GoalY: roomState.GoalY, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package system | ||
|
||
import ( | ||
"pkg.world.dev/world-engine/cardinal" | ||
|
||
comp "argus-exercise-1-backend/component" | ||
"argus-exercise-1-backend/msg" | ||
) | ||
|
||
func MoverSystem(world cardinal.WorldContext) error { | ||
return cardinal.EachMessage[msg.MoveMsg, msg.MoveMsgReply]( | ||
world, | ||
func(move cardinal.TxData[msg.MoveMsg]) (msg.MoveMsgReply, error) { | ||
roomID, room, err := queryTargetRoom(world, move.Tx.PersonaTag) | ||
if err != nil { | ||
return msg.MoveMsgReply{}, err | ||
} | ||
|
||
switch move.Msg.Direction { | ||
case msg.Up: | ||
if room.PlayerY > 0 { | ||
room.PlayerY-- | ||
} | ||
case msg.Down: | ||
if room.PlayerY < yLimit-1 { | ||
room.PlayerY++ | ||
} | ||
case msg.Left: | ||
if room.PlayerX > 0 { | ||
room.PlayerX-- | ||
} | ||
case msg.Right: | ||
if room.PlayerX < xLimit-1 { | ||
room.PlayerX++ | ||
} | ||
} | ||
|
||
err = cardinal.SetComponent[comp.Room](world, roomID, room) | ||
|
||
if err != nil { | ||
return msg.MoveMsgReply{}, err | ||
} | ||
|
||
return msg.MoveMsgReply{Success: true}, nil | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package system | ||
|
||
import ( | ||
"pkg.world.dev/world-engine/cardinal" | ||
|
||
"argus-exercise-1-backend/msg" | ||
) | ||
|
||
func RoomDeleterSystem(world cardinal.WorldContext) error { | ||
return cardinal.EachMessage[msg.DeleteRoomMsg, msg.DeleteRoomResult]( | ||
world, | ||
func(del cardinal.TxData[msg.DeleteRoomMsg]) (msg.DeleteRoomResult, error) { | ||
roomID, _, err := queryTargetRoom(world, del.Msg.Owner) | ||
if err != nil { | ||
return msg.DeleteRoomResult{}, err | ||
} | ||
|
||
err = cardinal.Remove(world, roomID) | ||
if err != nil { | ||
return msg.DeleteRoomResult{}, err | ||
} | ||
|
||
return msg.DeleteRoomResult{Success: true}, nil | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package system | ||
|
||
import ( | ||
"crypto/rand" | ||
"fmt" | ||
"math/big" | ||
|
||
"pkg.world.dev/world-engine/cardinal" | ||
|
||
comp "argus-exercise-1-backend/component" | ||
"argus-exercise-1-backend/msg" | ||
) | ||
|
||
const ( | ||
xLimit = 9 | ||
yLimit = 9 | ||
// player starts at bottom center | ||
playerInitialX = 4 | ||
playerInitialY = 8 | ||
) | ||
|
||
func secureIntn(xLimit int) (int, error) { | ||
n, err := rand.Int(rand.Reader, big.NewInt(int64(xLimit))) | ||
if err != nil { | ||
return 0, err | ||
} | ||
return int(n.Int64()), nil | ||
} | ||
|
||
func randomizeGoal() (int, int, error) { | ||
goalX, err := secureIntn(xLimit) | ||
if err != nil { | ||
return 0, 0, err | ||
} | ||
|
||
goalY, err := secureIntn(yLimit) | ||
if err != nil { | ||
return 0, 0, err | ||
} | ||
|
||
if goalX == playerInitialX && goalY == playerInitialY { | ||
return randomizeGoal() // Recursive call if the goal is same as player’s initial position | ||
} | ||
|
||
return goalX, goalY, nil | ||
} | ||
|
||
func RoomSpawnerSystem(world cardinal.WorldContext) error { | ||
return cardinal.EachMessage[msg.CreateRoomMsg, msg.CreateRoomResult]( | ||
world, | ||
func(create cardinal.TxData[msg.CreateRoomMsg]) (msg.CreateRoomResult, error) { | ||
goalX, goalY, err := randomizeGoal() | ||
if err != nil { | ||
return msg.CreateRoomResult{}, fmt.Errorf("error randomizing goal: %w", err) | ||
} | ||
room := comp.Room{ | ||
Owner: create.Tx.PersonaTag, | ||
PlayerX: playerInitialX, | ||
PlayerY: playerInitialY, | ||
GoalX: goalX, | ||
GoalY: goalY, | ||
} | ||
id, err := cardinal.Create(world, room) | ||
if err != nil { | ||
return msg.CreateRoomResult{}, fmt.Errorf("error creating room: %w", err) | ||
} | ||
|
||
err = world.EmitEvent(map[string]any{ | ||
"event": "new_room", | ||
"id": id, | ||
}) | ||
if err != nil { | ||
return msg.CreateRoomResult{}, err | ||
} | ||
return msg.CreateRoomResult{Success: true}, nil | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package system | ||
|
||
import ( | ||
"fmt" | ||
|
||
"pkg.world.dev/world-engine/cardinal" | ||
"pkg.world.dev/world-engine/cardinal/filter" | ||
"pkg.world.dev/world-engine/cardinal/types" | ||
|
||
comp "argus-exercise-1-backend/component" | ||
) | ||
|
||
// queryTargetRoom queries for the target room’s entity ID and room component. | ||
func queryTargetRoom(world cardinal.WorldContext, targetOwner string) (types.EntityID, *comp.Room, error) { | ||
var roomID types.EntityID | ||
var room *comp.Room | ||
var err error | ||
searchErr := cardinal.NewSearch().Entity( | ||
filter.Exact(filter.Component[comp.Room]())).Each(world, | ||
func(id types.EntityID) bool { | ||
var currentRoom *comp.Room | ||
currentRoom, err = cardinal.GetComponent[comp.Room](world, id) | ||
if err != nil { | ||
return false | ||
} | ||
|
||
// Terminates the search if the room is found | ||
if currentRoom.Owner == targetOwner { | ||
roomID = id | ||
room = currentRoom | ||
return false | ||
} | ||
|
||
// Continue searching if the room is not the target room | ||
return true | ||
}) | ||
if searchErr != nil { | ||
return 0, nil, err | ||
} | ||
if err != nil { | ||
return 0, nil, err | ||
} | ||
if room == nil { | ||
return 0, nil, fmt.Errorf("room %q does not exist", targetOwner) | ||
} | ||
|
||
return roomID, room, err | ||
} |