blockerseps

package
v0.0.0-...-07f0968 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2022 License: MIT Imports: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	Eps = []*app.Endpoint{
		{
			Description:  "Create a new game",
			Path:         (&blockers.New{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return nil
			},
			GetExampleArgs: func() interface{} {
				return nil
			},
			GetExampleResponse: func() interface{} {
				return NewGame()
			},
			Handler: func(tlbx app.Tlbx, _ interface{}) interface{} {
				g := NewGame()
				game.New(tlbx, gameType, g)
				return g
			},
		},
		{
			Description:  "Join a new game",
			Path:         (&blockers.Join{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &blockers.Join{}
			},
			GetExampleArgs: func() interface{} {
				return &blockers.Join{
					Game: app.ExampleID(),
				}
			},
			GetExampleResponse: func() interface{} {
				return NewGame()
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				args := a.(*blockers.Join)
				return game.Join(tlbx, pieceSetsCount, gameType, args.Game, &blockers.Game{})
			},
		},
		{
			Description:  "Start your current game",
			Path:         (&blockers.Start{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &blockers.Start{
					RandomizePlayerOrder: false,
				}
			},
			GetExampleArgs: func() interface{} {
				return &blockers.Start{
					RandomizePlayerOrder: true,
				}
			},
			GetExampleResponse: func() interface{} {
				return NewGame()
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				args := a.(*blockers.Start)
				return game.Start(tlbx, minPlayers, args.RandomizePlayerOrder, gameType, &blockers.Game{}, nil)
			},
		},
		{
			Description:  "Take your turn",
			Path:         (&blockers.TakeTurn{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &blockers.TakeTurn{}
			},
			GetExampleArgs: func() interface{} {
				return &blockers.TakeTurn{}
			},
			GetExampleResponse: func() interface{} {
				return NewGame()
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				args := a.(*blockers.TakeTurn)
				return game.TakeTurn(tlbx, gameType, &blockers.Game{}, func(a game.Game) {
					g := a.(*blockers.Game)
					turn := g.Base.Turn
					pieceSet := uint8(turn % uint32(pieceSetsCount))
					if args.End.Bool() {
						if !(pieceSet == 3 && len(g.Players) == 3) {

							g.PieceSetsEnded[pieceSet] = 1
						}
					} else {

						app.BadReqIf(
							args.Piece >= blockers.PiecesCount(),
							"invalid piece value: %d, must be less than: %d", args.Piece, blockers.PiecesCount())

						app.BadReqIf(
							g.PieceSets[pieceSet*blockers.PiecesCount()+args.Piece] == 0,
							"invalid piece, that piece has already been used")

						piece := blockers.GetPiece(args.Piece)

						if args.Flip.Bool() {
							flippedShape := make(Bits, len(piece.Shape))
							for y := uint8(0); y < piece.BB[1]; y++ {
								for x := uint8(0); x < piece.BB[0]; x++ {
									flippedShape[(y*piece.BB[0])+x] = piece.Shape[(y*piece.BB[0])+piece.BB[0]-1-x]
								}
							}
							piece.Shape = flippedShape
						}

						args.Rotation = args.Rotation % 4
						for i := uint8(0); i < args.Rotation; i++ {
							rotatedShape := make(Bits, len(piece.Shape))
							for y := uint8(0); y < piece.BB[1]; y++ {
								for x := uint8(0); x < piece.BB[0]; x++ {
									rotatedShape[(x*piece.BB[1])+(piece.BB[1]-1-y)] = piece.Shape[(y*piece.BB[0])+x]
								}
							}
							piece.Shape = rotatedShape
							bb0 := piece.BB[0]
							piece.BB[0] = piece.BB[1]
							piece.BB[1] = bb0
						}

						x, y := iToXY(args.Position, boardDims)
						app.BadReqIf(
							x+piece.BB[0] > uint8(boardDims) || y+piece.BB[1] > uint8(boardDims),
							"piece/position/rotation combination is not contained on the board")

						pieceSetStartI := pieceSetBoardStartI(pieceSet)

						firstCornerConMet := g.Board[pieceSetStartI] != 4

						cornerConMet := !firstCornerConMet

						insertIdxs := make([]uint16, 0, 5)
						posX, posY := iToXY(args.Position, boardDims)
						for pieceY := uint8(0); pieceY < piece.BB[1]; pieceY++ {
							for pieceX := uint8(0); pieceX < piece.BB[0]; pieceX++ {
								if piece.Shape[(pieceY*piece.BB[0])+pieceX] == 1 {
									cellX := posX + pieceX
									cellY := posY + pieceY
									cellI := xyToI(cellX, cellY, boardDims)

									app.BadReqIf(g.Board[cellI] != 4, "cell %d already occupied", cellI)
									insertIdxs = append(insertIdxs, cellI)

									firstCornerConMet = firstCornerConMet || cellI == pieceSetStartI

									for offsetY := -1; offsetY < 2; offsetY++ {
										for offsetX := -1; offsetX < 2; offsetX++ {
											if offsetX == 0 && offsetY == 0 {

												continue
											}
											loopBoardX := int(cellX) + offsetX
											loopBoardY := int(cellY) + offsetY

											if loopBoardX >= 0 && loopBoardY >= 0 && loopBoardX < int(boardDims) && loopBoardY < int(boardDims) {
												loopI := xyToI(uint8(loopBoardX), uint8(loopBoardY), boardDims)

												cornerConMet = cornerConMet ||
													((offsetX != 0 || offsetY != 0) &&
														g.Board[loopI] == pbit.Pbit(pieceSet))
												app.BadReqIf((offsetX == 0 || offsetY == 0) &&
													g.Board[loopI] == pbit.Pbit(pieceSet),
													"face to face constraint not met, cell %d", loopI)
											}
										}
									}
								}
							}
						}
						app.BadReqIf(!firstCornerConMet, "first corner constraint not met")
						app.BadReqIf(!cornerConMet, "corner touch constraint not met")

						for _, i := range insertIdxs {
							g.Board[i] = pbit.Pbit(pieceSet)
						}

						g.PieceSets[pieceSet*blockers.PiecesCount()+args.Piece] = 0
					}

					pieceSetsStillActive := make([]uint8, 0, pieceSetsCount)
					for j := uint8(0); j < pieceSetsCount; j++ {

						if j == 3 && len(g.Players) == 3 {
							continue
						}
						if g.PieceSetsEnded[j] == 0 {
							for i := uint8(0); i < blockers.PiecesCount(); i++ {
								if g.PieceSets[blockers.PiecesCount()*j+i] == 1 {
									pieceSetsStillActive = append(pieceSetsStillActive, j)
									break
								}
								if i+1 == blockers.PiecesCount() {

									g.PieceSetsEnded[j] = 1
								}
							}
						}
					}
					if len(pieceSetsStillActive) == 0 {
						g.State = 2
					} else {

						for i := uint8(1); i <= pieceSetsCount; i++ {
							if g.PieceSetsEnded[(pieceSet+i)%pieceSetsCount] == 0 {
								break
							}
							g.Turn++
						}
					}
				})
			},
		},
		{
			Description:  "Get a game",
			Path:         (&blockers.Get{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return &blockers.Get{}
			},
			GetExampleArgs: func() interface{} {
				return &blockers.Get{
					Game: app.ExampleID(),
				}
			},
			GetExampleResponse: func() interface{} {
				return NewGame()
			},
			Handler: func(tlbx app.Tlbx, a interface{}) interface{} {
				args := a.(*blockers.Get)
				return game.Get(tlbx, gameType, args.Game, args.UpdatedAfter, &blockers.Game{})
			},
		},
		{
			Description:  "Abandon your active game",
			Path:         (&blockers.Abandon{}).Path(),
			Timeout:      500,
			MaxBodyBytes: app.KB,
			IsPrivate:    false,
			GetDefaultArgs: func() interface{} {
				return nil
			},
			GetExampleArgs: func() interface{} {
				return nil
			},
			GetExampleResponse: func() interface{} {
				return nil
			},
			Handler: func(tlbx app.Tlbx, _ interface{}) interface{} {
				game.Abandon(tlbx, gameType, &blockers.Game{})
				return nil
			},
		},
	}
)

Functions

func NewGame

func NewGame() *blockers.Game

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL