Initial commit

implemented the game of life variation with hexagonal grid
This commit is contained in:
2025-12-16 11:33:00 +00:00
commit ea5b5c4e75
17 changed files with 1229 additions and 0 deletions

37
math/comp.go Normal file
View File

@@ -0,0 +1,37 @@
package math
func Max[T SignedNumber](nLst ...T) T {
switch len(nLst) {
case 0:
var zeroT T
return zeroT
case 1:
return nLst[0]
default:
m := nLst[0]
for _, n := range nLst[1:] {
if m < n {
m = n
}
}
return m
}
}
func Min[T SignedNumber](nLst ...T) T {
switch len(nLst) {
case 0:
var zeroT T
return zeroT
case 1:
return nLst[0]
default:
m := nLst[0]
for _, n := range nLst[1:] {
if m > n {
m = n
}
}
return m
}
}

75
math/comp_test.go Normal file
View File

@@ -0,0 +1,75 @@
package math
import (
"testing"
)
func TestMax(t *testing.T) {
testCases := []struct {
name string
values []int
exp int
}{
{
name: "multiple unique",
values: []int{3, 2, 4, 1},
exp: 4,
},
{
name: "single",
values: []int{5},
exp: 5,
},
{
name: "empty",
},
{
name: "multiple duplicates",
values: []int{2, 2, 2, 1},
exp: 2,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
act := Max(tc.values...)
if tc.exp != act {
t.Fatalf("want %v but got %v", tc.exp, act)
}
})
}
}
func TestMin(t *testing.T) {
testCases := []struct {
name string
values []int
exp int
}{
{
name: "multiple unique",
values: []int{3, 2, 4, 1},
exp: 1,
},
{
name: "single",
values: []int{5},
exp: 5,
},
{
name: "empty",
},
{
name: "multiple duplicates",
values: []int{2, 1, 1, 1},
exp: 1,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
act := Min(tc.values...)
if tc.exp != act {
t.Fatalf("want %v but got %v", tc.exp, act)
}
})
}
}

5
math/const.go Normal file
View File

@@ -0,0 +1,5 @@
package math
import "math"
const Pi = math.Pi

39
math/ops.go Normal file
View File

@@ -0,0 +1,39 @@
package math
import (
"math"
)
type SignedNumber interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~float32 | ~float64
}
type Float interface {
~float32 | ~float64
}
func Abs[T SignedNumber](i T) T {
var zero T
if i < zero {
return -i
}
return i
}
func Round[T Float](n T, precision int) T {
if precision == 0 {
return T(math.Round(float64(n)))
}
ratio := math.Pow(10, float64(precision))
f := math.Round(float64(n)*ratio) / ratio
return T(f)
}
func RoundInt[T Float](n T) int {
return int(Round(n, 0))
}
func Sqrt[T Float](n T) T {
return T(math.Sqrt(float64(n)))
}

47
math/ops_test.go Normal file
View File

@@ -0,0 +1,47 @@
package math
import (
"testing"
)
func TestAbs(t *testing.T) {
assertEqual(t, 0, Abs(0))
assertEqual(t, 1, Abs(1))
assertEqual(t, 2, Abs(-2))
assertEqual(t, 0.0, Abs(0.0))
assertEqual(t, 1.5, Abs(1.5))
assertEqual(t, 2.75, Abs(-2.75))
}
func TestRoundPositive(t *testing.T) {
posf64 := float64(0.987654321)
posf64 = Round(posf64, 2)
assertEqual(t, float64(0.99), posf64)
posf32 := float32(0.987654321)
posf32 = Round(posf32, 5)
assertEqual(t, float32(0.98765), posf32)
negf64 := float64(-0.987654321)
negf64 = Round(negf64, 2)
assertEqual(t, float64(-0.99), negf64)
negf32 := float32(-0.987654321)
negf32 = Round(negf32, 5)
assertEqual(t, float32(-0.98765), negf32)
}
func TestRoundInt(t *testing.T) {
i := RoundInt(float64(0.5))
assertEqual(t, 1, i)
i = RoundInt(float32(1.4999999))
assertEqual(t, 1, i)
}
func assertEqual[T comparable](t testing.TB, want, got T) {
if want != got {
t.Fatalf("want %v but got %v", want, got)
}
}

19
math/pair.go Normal file
View File

@@ -0,0 +1,19 @@
package math
import "fmt"
type Pair[T SignedNumber] struct {
X, Y T
}
func NewPair[T SignedNumber](x, y T) Pair[T] {
return Pair[T]{X: x, Y: y}
}
func (p Pair[T]) Equal(other Pair[T]) bool {
return p.X == other.X && p.Y == other.Y
}
func (c Pair[T]) String() string {
return fmt.Sprintf("(%v,%v)", c.X, c.Y)
}