-
Notifications
You must be signed in to change notification settings - Fork 418
feat(examples): pokemon fight simulator game at r/leo/pokemon
#4072
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat(examples): pokemon fight simulator game at r/leo/pokemon
#4072
Conversation
🛠 PR Checks SummaryAll Automated Checks passed. ✅ Manual Checks (for Reviewers):
Read More🤖 This bot helps streamline PR reviews by verifying automated checks and providing guidance for contributors and reviewers. ✅ Automated Checks (for Contributors):🟢 Maintainers must be able to edit this pull request (more info) ☑️ Contributor Actions:
☑️ Reviewer Actions:
📚 Resources:Debug
|
Codecov ReportAll modified and coverable lines are covered by tests ✅ 📢 Thoughts on this report? Let us know! |
14b4c01
to
6be7a81
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leaving some comments
Also please check the CI! |
…m-pokemon-game-for-demo
…m-pokemon-game-for-demo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, leaving some comments.
There are a couple of things that could be improved generally, like code readability, comments, etc. Go (and Gno) code should strive to be clean, readable, straightforward whenever possible. This is a pretty cool game and I can't wait to have it on the chain, so please fix up the comments and we'll get it moving :)
Apart from this you will have to implement the Inter-realm changes into your app soon.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this and publish it permissionlessly, as it's just some text render.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll juste remove it since it doesn't showcase any concrete gno usage acd5857
examples/gno.land/p/leo/dao/dao.gno
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a good learning for you guys. Now that we have packages like commondao, I suggest you use them to make DAOs. Try it out via p/nt/commondao or r/nt/commondao (the factory)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely removed DAO since i only used it for member managing 36e9afc
for i := teamSize; i < len(state); i += 2 { | ||
actionParam := state[i+1] - '0' | ||
switch state[i] { | ||
case 's': | ||
if me.team[actionParam].name != "" { | ||
game.myPokemon = &me.team[actionParam] | ||
} else { | ||
err = errors.New("invalid swap : " + string(state[i+1])) | ||
} | ||
case 'a': | ||
if game.myPokemon != nil && game.myPokemon.pv > 0 && game.myPokemon.attacks[actionParam].pc > 0 { | ||
game.myPokemon.attacks[actionParam].pc -= 1 | ||
game.otherPokemon.pv -= game.myPokemon.attacks[actionParam].damage | ||
if game.otherPokemon.pv <= 0 { | ||
for i := 0; i < teamSize; i++ { | ||
if game.otherTeam[i].pv > 0 { | ||
game.otherPokemon = &game.otherTeam[i] | ||
break | ||
} | ||
} | ||
} | ||
} else { | ||
err = errors.New("invalid ally attack : " + string(state[i+1])) | ||
} | ||
case 'i': | ||
if game.myPokemon != nil && len(me.inventory) > int(actionParam) { | ||
itemData[me.inventory[actionParam]].applyer(game.myPokemon) | ||
me.inventory = append(me.inventory[:actionParam], me.inventory[actionParam+1:]...) | ||
} else { | ||
err = errors.New("invalid item use : " + string(state[i+1])) | ||
} | ||
case 'e': | ||
if game.otherPokemon != nil && game.otherPokemon.pv > 0 && game.otherPokemon.attacks[actionParam].pc > 0 { | ||
game.otherPokemon.attacks[actionParam].pc -= 1 | ||
game.myPokemon.pv -= game.otherPokemon.attacks[actionParam].damage | ||
} else { | ||
err = errors.New("invalid enemy attack : " + string(state[i+1])) | ||
} | ||
default: | ||
err = errors.New("invalid action : " + string(state[i])) | ||
} | ||
if checkGameEnd(me.team, &game) { | ||
return | ||
} | ||
} | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit hard to read/understand without context. Do you think it could be 1) optimized, written more cleanly 2) commented so that the reader has more context on what's each case supposed to mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I optimised it using a function pointer map
eda6c09
// getEnnemyNextAttack selects a random valid attack for the enemy Pokémon | ||
func getEnnemyNextAttack(p *Pokemon) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo
// getEnnemyNextAttack selects a random valid attack for the enemy Pokémon | |
func getEnnemyNextAttack(p *Pokemon) string { | |
// getEnemyNextAttack selects a random valid attack for the enemy Pokémon | |
func getEnemyNextAttack(p *Pokemon) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
// renderTeamSwap renders the team swap interface for the player | ||
func renderTeamSwap(game GameState, team [teamSize]Pokemon, user, state string) (rend string) { | ||
have_pokemon := false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
camel case is nicer for go :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
table := mdtable.Table{Headers: []string{"Swap for "}, Rows: [][]string{[]string{"HP"}}} | ||
for i, p := range team { | ||
if p.name == "" { | ||
continue | ||
} | ||
have_pokemon = true | ||
if &team[i] == game.myPokemon { | ||
table.Headers = append(table.Headers, "Selected : "+p.name+md.Image(p.name, p.assetPath)) | ||
} else { | ||
link := getFightLink(user, state) + "s" + strconv.Itoa(i) | ||
table.Headers = append(table.Headers, md.Link(p.name, link)+md.InlineImageWithLink(p.name, p.assetPath, link)) | ||
} | ||
if p.pv > 0 { | ||
table.Rows[0] = append(table.Rows[0], strconv.Itoa(p.pv)+" / "+strconv.Itoa(p.getDefault().pv)) | ||
} else { | ||
table.Rows[0] = append(table.Rows[0], strconv.Itoa(0)+" / "+strconv.Itoa(p.getDefault().pv)) | ||
} | ||
} | ||
if !have_pokemon { | ||
rend += "Team : " + md.Bold("None !") + nl | ||
} else { | ||
rend += nl + table.String() | ||
} | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as before. the code is a bit hard to read/understand initially. It could be made better with some comments, optimization, and cleaner writing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// renderInventoryUse renders the player's inventory for item usage | ||
func renderInventoryUse(inventory []ItemType, user, state string) (rend string) { | ||
if len(inventory) != 0 { | ||
table := mdtable.Table{Headers: []string{"Item", "Description"}} | ||
for i, e := range inventory { | ||
table.Append([]string{md.Link("Use "+itemData[e].name, getFightLink(user, state)+"i"+strconv.Itoa(i)), itemData[e].description}) | ||
} | ||
rend += nl + table.String() | ||
} else { | ||
rend += "Inventory : " + md.Bold("Empty !") + nl | ||
} | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of points here:
Practice early returns; no need for the else statement here. See code below; much cleaner.
if len(inventory) == 0 {
return "Inventory : " + md.Bold("Empty !") + nl
}
table := mdtable.Table{Headers: []string{"Item", "Description"}}
for i, e := range inventory {
table.Append([]string{md.Link("Use "+itemData[e].name, getFightLink(user, state)+"i"+strconv.Itoa(i)), itemData[e].description})
}
return nl + table.String()
Two more things:
- if you have return values in your function, please return them explicitly
- There is no need to name the return values unless its hard to understand what's what, when there are multiple ones. In this case, it's obvious with context that "render" returns a string to render out. Being able to name return vars is not meant to be used to shorten your package by one line of code, unless size is really critical :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
|
||
// renderFightPokemon renders a Pokémon's details and attack options for the fight page | ||
func renderFightPokemon(p *Pokemon, user, state string, canAttack bool, otherP *Pokemon) (rend string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment about the return value as before
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rend += md.Link("Go back to lobby", atmPath+":lobby?user="+user) + nl | ||
} | ||
if game.state == gameLoose { | ||
rend += md.H3("You LOOSE...") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rend += md.H3("You LOOSE...") | |
rend += md.H3("You LOSE...") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
Realms:
r/leo/pokemon
A small Pokémon fight simulator game to showcase what a ranked game could look like using blockchain.
p/leo/randomizer
bymath/rand
p/leo/renderer
byp/moul/md
andp/moul/mdtable