Resolve display not appearing square at size 3
This commit is contained in:
parent
7fe65c1183
commit
886f47787d
9 changed files with 203 additions and 120 deletions
|
@ -106,7 +106,7 @@ func resetPlayerSettingsForm() {
|
|||
|
||||
// BS 1: 10x10
|
||||
// BS 2: 20x20
|
||||
// BS 3: 30x40
|
||||
// BS 3: 40x40
|
||||
func handleResize(screen tcell.Screen) {
|
||||
newScreenW, newScreenH = screen.Size()
|
||||
if newScreenW == screenW && newScreenH == screenH {
|
||||
|
@ -116,9 +116,9 @@ func handleResize(screen tcell.Screen) {
|
|||
screenW, screenH = newScreenW, newScreenH
|
||||
|
||||
if !fixedBlockSize {
|
||||
if screenW >= 80 && screenH >= 46 {
|
||||
if screenW >= 106 && screenH >= 46 {
|
||||
blockSize = 3
|
||||
} else if screenW >= 80 && screenH >= 24 {
|
||||
} else if screenW >= 56 && screenH >= 24 {
|
||||
blockSize = 2
|
||||
} else {
|
||||
blockSize = 1
|
||||
|
@ -129,7 +129,7 @@ func handleResize(screen tcell.Screen) {
|
|||
if blockSize == 2 {
|
||||
xMultiplier = 2
|
||||
} else if blockSize == 3 {
|
||||
xMultiplier = 3
|
||||
xMultiplier = 4
|
||||
}
|
||||
|
||||
if blockSize == 1 {
|
||||
|
@ -165,7 +165,7 @@ func handleResize(screen tcell.Screen) {
|
|||
} else if blockSize == 2 {
|
||||
previewWidth = 10
|
||||
} else {
|
||||
previewWidth = 14
|
||||
previewWidth = 18
|
||||
}
|
||||
|
||||
multiplayerMatrixSize = ((screenW - screenPadding) - ((10 * xMultiplier) + previewWidth + 6)) / ((10 * xMultiplier) + 4)
|
||||
|
@ -177,7 +177,7 @@ func handleResize(screen tcell.Screen) {
|
|||
showLogLines = 1
|
||||
}
|
||||
|
||||
gameGrid.SetRows(screenPadding, mainHeight, inputHeight, -1).SetColumns(screenPadding+1, 4+(10*xMultiplier), previewWidth, -1)
|
||||
gameGrid.SetRows(screenPadding, mainHeight, inputHeight, -1).SetColumns(screenPadding+1, 3+(10*xMultiplier), previewWidth, -1)
|
||||
|
||||
draw <- event.DrawAll
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ func renderPlayerGUI() {
|
|||
} else if blockSize == 2 {
|
||||
renderBuffer.WriteString(fmt.Sprintf("\n Combo\n\n %d\n\n\n Timer\n\n %.0f\n\n\nPending\n\n %d\n\n\n Speed\n\n %s", combo, comboTime, m.PendingGarbage, speed))
|
||||
} else if blockSize == 3 {
|
||||
renderBuffer.WriteString(fmt.Sprintf("\n\n\n\n\n Combo\n\n %d\n\n\n\n\n\n Timer\n\n %.0f\n\n\n\n\n\n Pending\n\n %d\n\n\n\n\n\n Speed\n\n %s", combo, comboTime, m.PendingGarbage, speed))
|
||||
renderBuffer.WriteString(fmt.Sprintf("\n\n\n\n\n Combo\n\n %d\n\n\n\n\n\n Timer\n\n %.0f\n\n\n\n\n\n Pending\n\n %d\n\n\n\n\n\n Speed\n\n %s", combo, comboTime, m.PendingGarbage, speed))
|
||||
}
|
||||
|
||||
side.Clear()
|
||||
|
@ -366,6 +366,13 @@ func renderMultiplayerGUI() {
|
|||
}
|
||||
|
||||
func renderPlayerDetails(m *mino.Matrix, bs int) {
|
||||
xMultiplier := 1
|
||||
if bs == 2 {
|
||||
xMultiplier = 2
|
||||
} else if bs == 3 {
|
||||
xMultiplier = 4
|
||||
}
|
||||
|
||||
var buf string
|
||||
if !showDetails {
|
||||
buf = m.PlayerName
|
||||
|
@ -376,16 +383,16 @@ func renderPlayerDetails(m *mino.Matrix, bs int) {
|
|||
buf = fmt.Sprintf("%d / %d @ %d", m.GarbageSent, m.GarbageReceived, m.Speed)
|
||||
}
|
||||
}
|
||||
if len(buf) > m.W*bs {
|
||||
buf = buf[:m.W*bs]
|
||||
if len(buf) > m.W*xMultiplier {
|
||||
buf = buf[:m.W*xMultiplier]
|
||||
}
|
||||
|
||||
padBuf := ((m.W*bs - len(buf)) / 2) + 1
|
||||
padBuf := ((m.W*xMultiplier - len(buf)) / 2) + 1
|
||||
for i := 0; i < padBuf; i++ {
|
||||
renderBuffer.WriteRune(' ')
|
||||
}
|
||||
renderBuffer.WriteString(buf)
|
||||
padBuf = m.W*bs + 2 - len(buf) - padBuf
|
||||
padBuf = m.W*xMultiplier + 2 - len(buf) - padBuf
|
||||
for i := 0; i < padBuf; i++ {
|
||||
renderBuffer.WriteRune(' ')
|
||||
}
|
||||
|
@ -407,15 +414,25 @@ func renderMatrixes(mx []*mino.Matrix) {
|
|||
renderBuffer.WriteRune('\n')
|
||||
if mx[0].Bag != nil {
|
||||
p := mx[0].Bag.Next()
|
||||
nextPieceWidth, _ = p.Size()
|
||||
if nextPieceWidth == 2 && blockSize == 1 {
|
||||
nextPieceWidth = 3
|
||||
if p != nil {
|
||||
nextPieceWidth, _ = p.Size()
|
||||
}
|
||||
}
|
||||
|
||||
if bs == 3 {
|
||||
renderBuffer.WriteRune('\n')
|
||||
}
|
||||
} else if mt == mino.MatrixCustom {
|
||||
bs = 1
|
||||
}
|
||||
|
||||
xMultiplier := 1
|
||||
if bs == 2 {
|
||||
xMultiplier = 2
|
||||
} else if bs == 3 {
|
||||
xMultiplier = 4
|
||||
}
|
||||
|
||||
for i := range mx {
|
||||
mx[i].Lock()
|
||||
mx[i].DrawPiecesL()
|
||||
|
@ -428,7 +445,7 @@ func renderMatrixes(mx []*mino.Matrix) {
|
|||
}
|
||||
|
||||
renderBuffer.Write(renderULCorner)
|
||||
for x := 0; x < mx[i].W*bs; x++ {
|
||||
for x := 0; x < mx[i].W*xMultiplier; x++ {
|
||||
renderBuffer.Write(renderHLine)
|
||||
}
|
||||
renderBuffer.Write(renderURCorner)
|
||||
|
@ -447,10 +464,6 @@ func renderMatrixes(mx []*mino.Matrix) {
|
|||
renderBuffer.Write(renderVLine)
|
||||
} else if m.Type == mino.MatrixPreview {
|
||||
renderBuffer.WriteRune(' ')
|
||||
|
||||
if nextPieceWidth < 4 {
|
||||
renderBuffer.WriteRune(' ')
|
||||
}
|
||||
}
|
||||
|
||||
for x := 0; x < m.W; x++ {
|
||||
|
@ -460,7 +473,7 @@ func renderMatrixes(mx []*mino.Matrix) {
|
|||
renderBuffer.Write(mino.Colors[m.Block(x, y)])
|
||||
renderBuffer.WriteRune(']')
|
||||
renderBuffer.WriteRune('▄')
|
||||
renderBuffer.Write([]byte("[-:-]"))
|
||||
renderBuffer.Write([]byte("[#FFFFFF:#000000]"))
|
||||
}
|
||||
|
||||
if m.Type == mino.MatrixStandard {
|
||||
|
@ -482,8 +495,7 @@ func renderMatrixes(mx []*mino.Matrix) {
|
|||
if m.Type == mino.MatrixStandard {
|
||||
renderBuffer.Write(renderVLine)
|
||||
} else if m.Type == mino.MatrixPreview {
|
||||
for pad := 0; pad < 3-nextPieceWidth; pad++ {
|
||||
renderBuffer.WriteRune(' ')
|
||||
if nextPieceWidth < 4 {
|
||||
renderBuffer.WriteRune(' ')
|
||||
}
|
||||
}
|
||||
|
@ -494,7 +506,7 @@ func renderMatrixes(mx []*mino.Matrix) {
|
|||
renderBuffer.WriteRune(']')
|
||||
renderBuffer.WriteRune('█')
|
||||
renderBuffer.WriteRune('█')
|
||||
renderBuffer.Write([]byte("[-]"))
|
||||
renderBuffer.Write([]byte("[#FFFFFF]"))
|
||||
}
|
||||
|
||||
if m.Type == mino.MatrixStandard {
|
||||
|
@ -517,10 +529,7 @@ func renderMatrixes(mx []*mino.Matrix) {
|
|||
if m.Type == mino.MatrixStandard {
|
||||
renderBuffer.Write(renderVLine)
|
||||
} else if m.Type == mino.MatrixPreview {
|
||||
if nextPieceWidth == 2 {
|
||||
renderBuffer.WriteRune(' ')
|
||||
renderBuffer.WriteRune(' ')
|
||||
} else if nextPieceWidth < 4 {
|
||||
if nextPieceWidth < 4 {
|
||||
renderBuffer.WriteRune(' ')
|
||||
}
|
||||
}
|
||||
|
@ -532,7 +541,8 @@ func renderMatrixes(mx []*mino.Matrix) {
|
|||
renderBuffer.WriteRune('█')
|
||||
renderBuffer.WriteRune('█')
|
||||
renderBuffer.WriteRune('█')
|
||||
renderBuffer.Write([]byte("[-]"))
|
||||
renderBuffer.WriteRune('█')
|
||||
renderBuffer.Write([]byte("[#FFFFFF]"))
|
||||
}
|
||||
|
||||
if m.Type == mino.MatrixStandard {
|
||||
|
@ -554,7 +564,7 @@ func renderMatrixes(mx []*mino.Matrix) {
|
|||
}
|
||||
|
||||
renderBuffer.Write(renderLLCorner)
|
||||
for x := 0; x < mx[i].W*bs; x++ {
|
||||
for x := 0; x < mx[i].W*xMultiplier; x++ {
|
||||
renderBuffer.Write(renderHLine)
|
||||
}
|
||||
renderBuffer.Write(renderLRCorner)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"git.sr.ht/~tslocum/netris/pkg/mino"
|
||||
|
@ -10,63 +11,54 @@ func TestRenderMatrix(t *testing.T) {
|
|||
renderLock.Lock()
|
||||
defer renderLock.Unlock()
|
||||
|
||||
blockSize = 1
|
||||
for bs := 1; bs <= 3; bs++ {
|
||||
bs := bs // Capture
|
||||
|
||||
m, err := mino.NewTestMatrix()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Run(fmt.Sprintf("Size=%d", bs), func(t *testing.T) {
|
||||
blockSize = bs
|
||||
|
||||
m, err := mino.NewTestMatrix()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
m.AddTestBlocks()
|
||||
|
||||
mx := []*mino.Matrix{m}
|
||||
|
||||
renderMatrixes(mx)
|
||||
})
|
||||
}
|
||||
|
||||
m.AddTestBlocks()
|
||||
|
||||
mx := []*mino.Matrix{m}
|
||||
|
||||
renderMatrixes(mx)
|
||||
blockSize = 1
|
||||
}
|
||||
|
||||
func BenchmarkRenderStandardMatrix(b *testing.B) {
|
||||
func BenchmarkRenderMatrix(b *testing.B) {
|
||||
renderLock.Lock()
|
||||
defer renderLock.Unlock()
|
||||
|
||||
blockSize = 1
|
||||
for bs := 1; bs <= 3; bs++ {
|
||||
bs := bs // Capture
|
||||
|
||||
m, err := mino.NewTestMatrix()
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
b.Run(fmt.Sprintf("Size=%d", bs), func(b *testing.B) {
|
||||
blockSize = bs
|
||||
|
||||
m.AddTestBlocks()
|
||||
m, err := mino.NewTestMatrix()
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
mx := []*mino.Matrix{m}
|
||||
m.AddTestBlocks()
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
mx := []*mino.Matrix{m}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
renderMatrixes(mx)
|
||||
}
|
||||
}
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
|
||||
func BenchmarkRenderLargeMatrix(b *testing.B) {
|
||||
renderLock.Lock()
|
||||
defer renderLock.Unlock()
|
||||
|
||||
blockSize = 2
|
||||
|
||||
m, err := mino.NewTestMatrix()
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
m.AddTestBlocks()
|
||||
|
||||
mx := []*mino.Matrix{m}
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
renderMatrixes(mx)
|
||||
for i := 0; i < b.N; i++ {
|
||||
renderMatrixes(mx)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
blockSize = 1
|
||||
|
|
|
@ -427,10 +427,10 @@ func (g *Game) handleDistributeMatrixes() {
|
|||
|
||||
requiredPlayers := 2
|
||||
if g.Local {
|
||||
requiredPlayers = 0
|
||||
requiredPlayers = 1
|
||||
}
|
||||
|
||||
if !g.gameOver && remainingPlayers <= requiredPlayers {
|
||||
if !g.gameOver && remainingPlayers < requiredPlayers {
|
||||
g.setGameOverL(true)
|
||||
|
||||
if g.Local {
|
||||
|
|
|
@ -1,45 +1,50 @@
|
|||
package mino
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBag(t *testing.T) {
|
||||
var (
|
||||
minos []Mino
|
||||
err error
|
||||
)
|
||||
t.Parallel()
|
||||
|
||||
for _, d := range minoTestData {
|
||||
minos, err = Generate(d.Rank)
|
||||
if err != nil {
|
||||
t.Errorf("failed to generate minos for rank %d: %s", d.Rank, err)
|
||||
}
|
||||
d := d // Capture
|
||||
|
||||
if len(minos) != len(d.Minos) {
|
||||
t.Errorf("failed to generate minos for rank %d: unexpected number of minos generated", d.Rank)
|
||||
}
|
||||
t.Run(fmt.Sprintf("Rank=%d", d.Rank), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
b, err := NewBag(0, minos, 10)
|
||||
if err != nil {
|
||||
t.Errorf("failed to create bag for rank %d: %s", d.Rank, err)
|
||||
}
|
||||
|
||||
taken := make(map[string]int)
|
||||
for i := 1; i < 4; i++ {
|
||||
for i := 0; i < len(d.Minos); i++ {
|
||||
mino := b.Take()
|
||||
taken[mino.String()]++
|
||||
minos, err := Generate(d.Rank)
|
||||
if err != nil {
|
||||
t.Errorf("failed to generate minos for rank %d: %s", d.Rank, err)
|
||||
}
|
||||
|
||||
if len(taken) != len(minos) {
|
||||
t.Errorf("minos placed in rank %d bag do not match minos taken - placed: %s - taken: %v", d.Rank, minos, taken)
|
||||
if len(minos) != len(d.Minos) {
|
||||
t.Errorf("failed to generate minos for rank %d: unexpected number of minos generated", d.Rank)
|
||||
}
|
||||
|
||||
for _, mino := range minos {
|
||||
if taken[mino.String()] != i {
|
||||
t.Fatalf("minos placed in rank %d bag do not match minos taken - placed: %s - taken: %v", d.Rank, minos, taken)
|
||||
b, err := NewBag(0, minos, 10)
|
||||
if err != nil {
|
||||
t.Errorf("failed to create bag for rank %d: %s", d.Rank, err)
|
||||
}
|
||||
|
||||
taken := make(map[string]int)
|
||||
for i := 1; i < 4; i++ {
|
||||
for i := 0; i < len(d.Minos); i++ {
|
||||
mino := b.Take()
|
||||
taken[mino.String()]++
|
||||
}
|
||||
|
||||
if len(taken) != len(minos) {
|
||||
t.Errorf("minos placed in rank %d bag do not match minos taken - placed: %s - taken: %v", d.Rank, minos, taken)
|
||||
}
|
||||
|
||||
for _, mino := range minos {
|
||||
if taken[mino.String()] != i {
|
||||
t.Fatalf("minos placed in rank %d bag do not match minos taken - placed: %s - taken: %v", d.Rank, minos, taken)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,10 @@ import (
|
|||
)
|
||||
|
||||
func TestGenerate(t *testing.T) {
|
||||
var (
|
||||
minos []Mino
|
||||
err error
|
||||
)
|
||||
t.Parallel()
|
||||
|
||||
for _, d := range minoTestData {
|
||||
minos, err = Generate(d.Rank)
|
||||
minos, err := Generate(d.Rank)
|
||||
if err != nil {
|
||||
t.Errorf("failed to generate minos for rank %d: %s", d.Rank, err)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
)
|
||||
|
||||
func TestMatrix(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
m, err := NewTestMatrix()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -65,7 +67,7 @@ func TestMatrix(t *testing.T) {
|
|||
|
||||
ok = m.RotatePiece(1, 0)
|
||||
if !ok {
|
||||
t.Errorf("failed to rotate piece for right wall kick")
|
||||
t.Errorf("failed to rotate piece for right 1wall kick")
|
||||
}
|
||||
|
||||
for i := 0; i < 7; i++ {
|
||||
|
|
|
@ -44,6 +44,26 @@ const (
|
|||
PentominoR = "(0,0),(1,0),(2,0),(3,0),(1,1)"
|
||||
)
|
||||
|
||||
func NewMino(points string) Mino {
|
||||
var m Mino
|
||||
|
||||
var last int
|
||||
for i, p := range strings.Split(strings.ReplaceAll(strings.ReplaceAll(points, "(", ""), ")", ""), ",") {
|
||||
v, err := strconv.Atoi(p)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if i%2 == 0 {
|
||||
last = v
|
||||
continue
|
||||
}
|
||||
|
||||
m = append(m, Point{last, v})
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func (m Mino) Equal(other Mino) bool {
|
||||
if len(m) != len(other) {
|
||||
return false
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package mino
|
||||
|
||||
type Minos []Mino
|
||||
|
||||
func (ms Minos) Has(m Mino) bool {
|
||||
for _, msm := range ms {
|
||||
if msm.Equal(m) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
69
pkg/mino/piece_test.go
Normal file
69
pkg/mino/piece_test.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package mino
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type PieceTestData struct {
|
||||
R0 string
|
||||
RR string
|
||||
R2 string
|
||||
RL string
|
||||
}
|
||||
|
||||
var pieceTestData = []*PieceTestData{
|
||||
{Monomino, Monomino, Monomino, Monomino},
|
||||
{Domino, "(0,-1),(0,0)", Domino, "(0,-1),(0,0)"},
|
||||
}
|
||||
|
||||
func TestPiece(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// TODO Resolve CCW rotation resulting in different coords than CW rotation before completing test
|
||||
return
|
||||
|
||||
for i, d := range pieceTestData {
|
||||
m := NewMino(d.R0)
|
||||
if m == nil || m.String() != d.R0 {
|
||||
t.Errorf("failed to create mino %d %s: got %s", i, d.R0, m)
|
||||
}
|
||||
|
||||
p := NewPiece(m, Point{0, 0})
|
||||
if p == nil || p.Mino.String() != d.R0 {
|
||||
t.Errorf("failed to create piece %d %s: got %s", i, d.R0, p)
|
||||
}
|
||||
|
||||
for direction := 0; direction <= 1; direction++ {
|
||||
for rotations := 0; rotations < 8; rotations++ {
|
||||
p.Mino = p.Rotate(1, direction)
|
||||
expected := ""
|
||||
switch rotations % 4 {
|
||||
case 0:
|
||||
if direction == 0 {
|
||||
expected = d.RR
|
||||
} else {
|
||||
expected = d.RL
|
||||
}
|
||||
case 1:
|
||||
expected = d.R2
|
||||
case 2:
|
||||
if direction == 0 {
|
||||
expected = d.RL
|
||||
} else {
|
||||
expected = d.RR
|
||||
}
|
||||
case 3:
|
||||
expected = d.R0
|
||||
default:
|
||||
t.Errorf("unexpected rotation count %d", rotations)
|
||||
}
|
||||
if p.Mino.String() != expected {
|
||||
t.Errorf("failed to rotate piece %d - direction %d - rotation %d - expected %s: got %s", i, direction, rotations, expected, p.Mino)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Println(p)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue