Skip to content
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

Flippando - the game #2648

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
a09b866
scaffolding, test failing, wip
irreverentsimplicity Aug 9, 2023
df94cdd
tests passing
irreverentsimplicity Aug 9, 2023
fca910b
flipTiles in package, small refactoring
irreverentsimplicity Aug 10, 2023
e397ea4
start game function
irreverentsimplicity Aug 11, 2023
b67e85c
sqrt local implementation, start game tests
irreverentsimplicity Aug 12, 2023
f225fb8
sqrt, grc6150 type, tests, wip
irreverentsimplicity Aug 17, 2023
c6de0fc
add deploy script
irreverentsimplicity Aug 29, 2023
070e387
tests passing, rand implementation wip
irreverentsimplicity Aug 29, 2023
59e4d21
remove sqrt package, add render path placeholder
irreverentsimplicity Aug 29, 2023
ff9fb18
Merge remote-tracking branch 'upstream/master'
irreverentsimplicity Sep 14, 2023
d0ede7c
new tests
irreverentsimplicity Sep 15, 2023
bb79b49
Merge remote-tracking branch 'upstream/master'
irreverentsimplicity Sep 15, 2023
f2ae83f
refactored package and realm
irreverentsimplicity Sep 23, 2023
9bead3c
wip
irreverentsimplicity Oct 3, 2023
d760fec
ReadPerByte error
irreverentsimplicity Oct 8, 2023
c9f999b
refactor call
irreverentsimplicity Oct 8, 2023
979a465
testing
irreverentsimplicity Oct 8, 2023
cd66ce6
updating
irreverentsimplicity Oct 8, 2023
8faf92f
refactor board creation, working
irreverentsimplicity Oct 13, 2023
e04eb63
added svg functions, refactor game, game baord structs, basic svg tests
irreverentsimplicity Oct 14, 2023
cf9268c
refactored Game, GameBoard
irreverentsimplicity Oct 18, 2023
0085f09
amening broken nft implementation, wip
irreverentsimplicity Oct 20, 2023
34d5157
refactoring
irreverentsimplicity Oct 20, 2023
d52f087
random numbers on client
irreverentsimplicity Oct 30, 2023
d346266
igrc settokenuri
irreverentsimplicity Oct 30, 2023
e6d7aea
igrc settokenuri
irreverentsimplicity Oct 30, 2023
032ebe8
errors
irreverentsimplicity Oct 30, 2023
40f2094
grc calls
irreverentsimplicity Oct 31, 2023
1029b91
forcing new seed on initialization
irreverentsimplicity Nov 1, 2023
3b3bdfc
game half working
irreverentsimplicity Nov 2, 2023
725cc27
nft creation, wip, unstable
irreverentsimplicity Nov 3, 2023
aef94c6
playable game, nft creation without error, fetching nfts unstable
irreverentsimplicity Nov 5, 2023
ea5c539
fetching all nfts ok
irreverentsimplicity Nov 5, 2023
0eed85e
nft retrieval working, wip
irreverentsimplicity Nov 6, 2023
4a78c44
fetching user nfts
irreverentsimplicity Nov 7, 2023
7edfa8c
added dice rendering
irreverentsimplicity Nov 7, 2023
56b217a
grc20 implementation, wip
irreverentsimplicity Nov 8, 2023
e7458bf
hexagram backend generation
irreverentsimplicity Nov 8, 2023
be83426
composite nft backend, untested
irreverentsimplicity Nov 8, 2023
aa228ef
stabilize composite NFT mint and transfers, wip
irreverentsimplicity Nov 15, 2023
1773887
remove dependency on hacky math_rand
irreverentsimplicity Nov 22, 2023
728812d
more tests, fixing create composite nft
irreverentsimplicity Nov 24, 2023
a23b63d
Merge branch 'master' into feat/flippando
irreverentsimplicity Nov 24, 2023
890efa5
Merge branch 'master' into feat/flippando
irreverentsimplicity Nov 24, 2023
c41d9a7
fix composite nft bug
irreverentsimplicity Nov 24, 2023
1a7a78c
fixed the fungible token logic
irreverentsimplicity Nov 25, 2023
fb05499
refactor locked balances logic, wip, unstable
irreverentsimplicity Nov 25, 2023
3c73872
fixed locking and unlocking balances, removed 2nd avl.Tree
irreverentsimplicity Nov 27, 2023
9dd88ca
added new struct for keeping track of lockedNFTs, amended logic and f…
irreverentsimplicity Nov 28, 2023
45c4965
rng source
irreverentsimplicity Dec 6, 2023
036bd2a
added marketplace, wip, not working
irreverentsimplicity Dec 12, 2023
8eb295e
add tokenIds to listing
irreverentsimplicity Dec 13, 2023
7c6934d
marketplace functionality, wip
irreverentsimplicity Dec 13, 2023
05b0bd2
marketplace interaction, gradients
irreverentsimplicity Dec 16, 2023
e8f20ce
fix typos
irreverentsimplicity Dec 16, 2023
359c2e4
update basic and composite NFT with childOf / children, refactor mark…
irreverentsimplicity Dec 18, 2023
3fb123f
fix typos
irreverentsimplicity Dec 18, 2023
d5e32fd
refactored listing struct and marshals
irreverentsimplicity Dec 18, 2023
3ee6c2c
marketplace fixes, wip
irreverentsimplicity Dec 19, 2023
df53d7e
fix marketplace bugs, wip
irreverentsimplicity Dec 21, 2023
aeb07f7
merge master
irreverentsimplicity Jan 9, 2024
3ab0244
merge master
irreverentsimplicity Jan 9, 2024
aa62473
remove custom grc721 references from trunk
irreverentsimplicity Jan 9, 2024
7da7d22
remove custom grc721 references from codebase
irreverentsimplicity Jan 9, 2024
0faa0cb
add gradients to random range
irreverentsimplicity Jan 13, 2024
a4bf362
basic NFT and marketplace fixes, wip
irreverentsimplicity Jan 13, 2024
e769e26
64 tiles games completed
irreverentsimplicity Jan 13, 2024
ee41d66
fix bug for incorrect gameTiles saize, for different gameTypes
irreverentsimplicity Jan 13, 2024
4ca6815
fix all nft call param
irreverentsimplicity Jan 15, 2024
9cbf501
Merge branch 'master' into feat/flippando-testnet
Jan 15, 2024
c42a56a
change defautl return value
Jan 15, 2024
95656b7
backend logic and marshaling for user games result
irreverentsimplicity Jan 24, 2024
f0858db
backend call to get user games by status, working
irreverentsimplicity Jan 25, 2024
9ba5980
add tileType to game marshalling
irreverentsimplicity Jan 25, 2024
b710776
return user games by gameID, insted of always the last game
irreverentsimplicity Jan 26, 2024
787dc3f
Merge branch 'master' into feat/flippando-testnet
irreverentsimplicity Jan 31, 2024
ccce4e3
backend checks for dynamic canvas size
irreverentsimplicity Mar 13, 2024
126d4c7
Merge branch 'master' into feat/flippando-testnet
irreverentsimplicity Mar 29, 2024
f7dcb19
remove shadowing
irreverentsimplicity Mar 29, 2024
6019bee
remove shadowing
irreverentsimplicity Mar 29, 2024
e3df87f
Merge branch 'gnolang:master' into feat/flippando-testnet
irreverentsimplicity Mar 29, 2024
0273b67
airdrop, wip, not working
irreverentsimplicity May 12, 2024
f7b37de
Merge branch 'master' into feat/flippando-testnet
irreverentsimplicity May 12, 2024
d5f1a97
airdrop, wip, not working
irreverentsimplicity May 12, 2024
723b1fc
airdrop, wip, not working
irreverentsimplicity May 12, 2024
aeb4378
airdrop, wip, not working
irreverentsimplicity May 12, 2024
c776be5
update for errors.New
irreverentsimplicity May 12, 2024
46acc44
refactor for errors.New
irreverentsimplicity May 12, 2024
d18a85f
remove unused imports
irreverentsimplicity Jun 1, 2024
a3a2156
remove unused imports
irreverentsimplicity Jun 1, 2024
655ceff
amend return types
irreverentsimplicity Jun 1, 2024
8e4189c
amend return type
irreverentsimplicity Jun 1, 2024
4ea85fc
Merge branch 'master' into feat/flippando-testnet
irreverentsimplicity Jun 1, 2024
f0661de
amend marshals
irreverentsimplicity Jun 1, 2024
3a6a963
fix marshal bug, add burning func
irreverentsimplicity Jun 7, 2024
ae4bd7a
refactor marketplace to use map instead of avl.Tree
irreverentsimplicity Jun 8, 2024
09e6b9d
fixed the listing bug, refactore compositeNFT for map of children ins…
irreverentsimplicity Jun 9, 2024
871d06b
refactor: maps instead of avl.Tree, std.Coins for FLIP, SetApprovalFo…
irreverentsimplicity Jun 12, 2024
83251e7
solve buying bug by approving in each file of the realm
irreverentsimplicity Jun 18, 2024
a4c8ef5
cleanup
irreverentsimplicity Jun 19, 2024
c219484
remove unused var
irreverentsimplicity Jun 19, 2024
b99a4c5
fix bug when not enough FLIP balances
irreverentsimplicity Jun 21, 2024
aec183f
Merge branch 'master' into feat/flippando-testnet
irreverentsimplicity Jul 18, 2024
a094e21
fix FLIP allocation on 64 tiles
irreverentsimplicity Jul 18, 2024
92bf3ab
marketplace placeholder functions for basic NFTs, flippando calls for…
irreverentsimplicity Jul 18, 2024
d885930
basic NFTs listings and transfers logic
irreverentsimplicity Jul 19, 2024
092676c
airdrop script, check for airdrop requirements, struct updates
irreverentsimplicity Jul 20, 2024
a6c7570
fix typos
irreverentsimplicity Jul 20, 2024
05ef518
basic and composite NFT buying complete, composite NFT creation worki…
irreverentsimplicity Jul 28, 2024
6fad217
typos
irreverentsimplicity Jul 29, 2024
7c33075
separated airdrop realm, wip, not tested
irreverentsimplicity Jul 29, 2024
8ee1949
add getters for minted nfts, marshalling the result
irreverentsimplicity Jul 29, 2024
bf41f2e
refactor of mintedNFTs to account for extra airdrop information
irreverentsimplicity Jul 29, 2024
eb3ee29
cleanup
irreverentsimplicity Jul 29, 2024
6342086
extra logging, airdrop logic
irreverentsimplicity Jul 29, 2024
5f39862
fix error in marshaling basicNFT, mint airdrop nft in correct order
irreverentsimplicity Jul 29, 2024
768a440
flippando airdrop feature complete
irreverentsimplicity Jul 31, 2024
bb2db3e
Merge branch 'gnolang:master' into feat/airdrop
irreverentsimplicity Jul 31, 2024
38da6b3
cleanup
irreverentsimplicity Jul 31, 2024
0832462
Merge branch 'feat/airdrop' of https://github.com/irreverentsimplicit…
irreverentsimplicity Jul 31, 2024
ad890b5
cleanup math_rand
irreverentsimplicity Jul 31, 2024
de6999a
grc6150 cleanup
irreverentsimplicity Jul 31, 2024
ce69a98
atomic cleanup
irreverentsimplicity Jul 31, 2024
e5a515e
sync cleanup
irreverentsimplicity Jul 31, 2024
4188f20
upgradeable cleanup
irreverentsimplicity Jul 31, 2024
872ec9d
uflippando cleanup
irreverentsimplicity Jul 31, 2024
f5f03bd
shell scripts cleanup
irreverentsimplicity Jul 31, 2024
4350677
refactor error messages, replaces panics
irreverentsimplicity Aug 4, 2024
78da0e6
backend check for double minting of the same airdrop nft, checking fo…
irreverentsimplicity Aug 10, 2024
2f04c37
Merge branch 'gnolang:master' into feat/airdrop
irreverentsimplicity Aug 12, 2024
889791b
fixed wrong selection of the saved bug on minting basic nft
irreverentsimplicity Aug 23, 2024
ce9c360
Merge branch 'feat/airdrop' of https://github.com/irreverentsimplicit…
irreverentsimplicity Aug 23, 2024
fe06f77
mint only homogenous NFTs, either airdropped or organic
irreverentsimplicity Aug 26, 2024
ecfac30
fix bug: basic NFTs cannot be listed by anyone
irreverentsimplicity Aug 26, 2024
e6de200
temporary fix test
irreverentsimplicity Aug 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions examples/gno.land/p/demo/flippandoserver/flippandoserver.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package flippandoserver

type GameBoard struct {
Board []int64 `json:"board"`
TileType string `json:"tileType"`
GameTiles []int64 `json:"gameTiles"`
BoardSize int `json:"boardSize"`
}

type positions struct {
position1 int
position2 int
}

// position1 - int, postion2 - int

type inTransit struct {
tokenId int
inTransit bool
}

// creates game object and initializes board
func CreateGameBoard(tileType string, boardSize int, seed int64) ([]int64, []int64, int) {
// Initialize the board and gameTiles slices based on boardSize
board := make([]int64, boardSize)

// Initialize the gameTiles slice with a length that is the square root of boardSize
gameTilesLength := int(sqrt(float64(boardSize)))
gameTiles := make([]int64, gameTilesLength)
// @todo make call to generateRandomNumbers, so you can create the actual gameTiles array,
rng := int64(4)
if tileType == "squareGrid" {
rng = int64(16)
} else if tileType == "greyGradient" || tileType == "redGradient" || tileType == "blueGradient" || tileType == "greenGradient" {
rng = int64(8)
} else if tileType == "hexagrams" {
rng = int64(4)
// adjust for bigger board
if len(gameTiles) == 8 {
gameTiles = make([]int64, 4)
}
} else if tileType == "dice" {
rng = int64(6)
// adjust for bigger board
if len(gameTiles) == 8 {
gameTiles = make([]int64, 6)
}
}
// Generating random numbers for gameTiles
generatedNumbers := GenerateRandomNumbers(len(gameTiles), 1, int(rng), seed)
for i, num := range generatedNumbers {
gameTiles[i] = int64(num)
}

// we're returning discrete value, and do the json marshaling in realm
return board, gameTiles, boardSize;
}

func FlipTiles(board []int64, solvedBoard []int64, gameTiles []int64, positions []int64, seed int64) ([]int64, []int64) {
// - returns the current game board, and the solved game board

randomNumberSlice := GenerateRandomNumbers(2, 1, len(gameTiles), seed)

// Safety check for 'positions' slice
if len(positions) < 2 {
return nil, nil
}

// Safety check for 'randomNumberSlice'
if randomNumberSlice == nil || len(randomNumberSlice) < 2 {
return nil, nil
}

// position hasn't been discovered before
if board[positions[0]] == 0 {
board[positions[0]] = gameTiles[randomNumberSlice[0] - 1]
}

if board[positions[1]] == 0 {
board[positions[1]] = gameTiles[randomNumberSlice[1] -1]
}

// values are equal, update solved board
if board[positions[0]] == board[positions[1]] {
solvedBoard[positions[0]] = board[positions[0]]
solvedBoard[positions[1]] = board[positions[1]]
}

// enforce solvability
quantumThreshold := int(sqrt(float64(len(board))))
unsolvedTiles := 0

for j := 0; j < len(board); j++ {
if solvedBoard[j] == 0 {
unsolvedTiles++
}
}

if unsolvedTiles <= quantumThreshold {
// replace the board with solvedBoard and redeploy
if board[positions[0]] != board[positions[1]] {
board[positions[0]] = board[positions[1]]
solvedBoard[positions[0]] = board[positions[0]]
solvedBoard[positions[1]] = board[positions[1]]
}
}

return board, solvedBoard

}

func GenerateRandomNumbers(howMany, min, max int, seed int64) []int {
if min > max || howMany <= 0 || (max-min+1) < howMany {
return nil
}

r := New(seed)
numbers := make([]int, 0, howMany)
seen := make(map[int]bool)

for len(numbers) < howMany {
randomNumber := r.Intn(max-min+1) + min

// If the number hasn't been generated before, add it to the slice and the map
if !seen[randomNumber] {
seen[randomNumber] = true
numbers = append(numbers, randomNumber)
}
}

return numbers
}


func sqrt(x float64) float64 {
if x == 0 || x == 1 {
return x
}

// Start with an initial guess
guess := x / 2.0
prevGuess := 0.0

// Use a small threshold to determine when to stop the approximation
const threshold = 0.00001

// Use math.Abs to calculate the absolute value
abs := func(f float64) float64 {
if f < 0 {
return -f
}
return f
}

for abs(guess-prevGuess) > threshold {
prevGuess = guess
guess = 0.5 * (guess + x/guess)
}

return guess
}
122 changes: 122 additions & 0 deletions examples/gno.land/p/demo/flippandoserver/flippandoserver_test.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package flippandoserver

import (
"sort"
"math"
"std"
"testing"
"time"
"encoding/json"
"strconv"
"errors"

"gno.land/p/demo/testutils"
"gno.land/p/demo/ufmt"
)

func TestCreateGameBoard(t *testing.T) {
tests := []struct {
name string
tileType string
boardSize int
seed int64
maxTileVal int
}{
{"SquareGrid", "squareGrid", 4, 12345, 16},
{"Hexagrams", "hexagrams", 4, 12345, 4},
{"Dice", "dice", 4, 12345, 6},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
board, gameTiles, size := CreateGameBoard(tt.tileType, tt.boardSize, tt.seed)

// Test the length of the board
if len(board) != tt.boardSize {
t.Errorf("Expected board length of %d, got %d", tt.boardSize, len(board))
}

// Test the length of gameTiles
expectedGameTilesLength := int(sqrt(float64(tt.boardSize)))
if len(gameTiles) != expectedGameTilesLength {
t.Errorf("Expected gameTiles length of %d, got %d", expectedGameTilesLength, len(gameTiles))
}

// Check if gameTiles values are within the expected range
for _, tile := range gameTiles {
if tile < 1 || tile > int64(tt.maxTileVal) {
t.Errorf("gameTiles contains a value out of expected range (1 to %d): got %d", tt.maxTileVal, tile)
}
}

// Check if the gameTiles values are unique
uniqueTiles := make(map[int64]bool)
for _, tile := range gameTiles {
if uniqueTiles[tile] {
t.Errorf("Duplicate tile found in gameTiles: %d", tile)
}
uniqueTiles[tile] = true
}

// Test the returned board size
if size != tt.boardSize {
t.Errorf("Expected returned board size to be %d, got %d", tt.boardSize, size)
}
})
}
}

func TestGenerateRandomNumbers(t *testing.T) {
tests := []struct {
howMany int
min int
max int
seed int64
expect int
}{
{5, 1, 10, 123, 5},
{3, 5, 7, 456, 3},
{10, 1, 5, 789, 0},
{0, 1, 10, 101, 0},
{-2, 1, 10, 112, 0},
{5, 10, 5, 123, 0},
}

for _, tt := range tests {
got := GenerateRandomNumbers(tt.howMany, tt.min, tt.max, tt.seed)

if len(got) != tt.expect {
t.Errorf("expected %d numbers but got %d", tt.expect, len(got))
}

// Check for uniqueness
numSet := make(map[int]bool)
for _, num := range got {
if numSet[num] {
t.Errorf("duplicate number found: %d", num)
}
numSet[num] = true
}

// Check if numbers are within range
for _, num := range got {
if num < tt.min || num > tt.max {
t.Errorf("number %d out of range [%d, %d]", num, tt.min, tt.max)
}
}
}
}


// Helper function to compare two slices for equality
func sliceEqual(a, b []int64) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}
Loading
Loading