September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -0,0 +1,118 @@
package main
import (
rl "github.com/gen2brain/raylib-go/raylib"
"math"
"strings"
)
type hexagon struct {
x, y float32
letter rune
selected bool
}
func (h hexagon) points(r float32) []rl.Vector2 {
res := make([]rl.Vector2, 7)
for i := 0; i < 7; i++ {
fi := float64(i)
res[i].X = h.x + r*float32(math.Cos(math.Pi*fi/3))
res[i].Y = h.y + r*float32(math.Sin(math.Pi*fi/3))
}
return res
}
func inHexagon(pts []rl.Vector2, pt rl.Vector2) bool {
rec := rl.NewRectangle(pts[4].X, pts[4].Y, pts[5].X-pts[4].X, pts[2].Y-pts[4].Y)
if rl.CheckCollisionPointRec(pt, rec) {
return true
}
if rl.CheckCollisionPointTriangle(pt, pts[2], pts[3], pts[4]) {
return true
}
if rl.CheckCollisionPointTriangle(pt, pts[0], pts[1], pts[5]) {
return true
}
return false
}
func main() {
screenWidth := int32(600)
screenHeight := int32(600)
rl.InitWindow(screenWidth, screenHeight, "Honeycombs")
rl.SetTargetFPS(60)
letters := "LRDGITPFBVOKANUYCESM"
runes := []rune(letters)
var combs [20]hexagon
var pts [20][]rl.Vector2
x1, y1 := 150, 100
x2, y2 := 225, 143
w, h := 150, 87
r := float32(w / 3)
for i := 0; i < 20; i++ {
var x, y int
if i < 12 {
x = x1 + (i%3)*w
y = y1 + (i/3)*h
} else {
x = x2 + (i%2)*w
y = y2 + (i-12)/2*h
}
combs[i] = hexagon{float32(x), float32(y), runes[i], false}
pts[i] = combs[i].points(r)
}
nChosen := 0
sChosen := "Chosen: "
lChosen := "Last chosen: "
for !rl.WindowShouldClose() {
rl.BeginDrawing()
rl.ClearBackground(rl.RayWhite)
for i, c := range combs {
ctr := pts[i][0]
ctr.X -= r
index := -1
if key := rl.GetKeyPressed(); key != -1 {
if key >= 97 && key <= 122 {
key -= 32
}
index = strings.IndexRune(letters, key)
} else if rl.IsMouseButtonPressed(rl.MouseLeftButton) {
pt := rl.Vector2{float32(rl.GetMouseX()), float32(rl.GetMouseY())}
for i := 0; i < 20; i++ {
if inHexagon(pts[i], pt) {
index = i
break
}
}
}
if index >= 0 {
if !combs[index].selected {
combs[index].selected = true
nChosen++
s := string(combs[index].letter)
sChosen += s
lChosen = "Last chosen: " + s
if nChosen == 20 {
lChosen += " (All 20 Chosen!)"
}
}
}
if !c.selected {
rl.DrawPoly(ctr, 6, r-1, 30, rl.Yellow)
} else {
rl.DrawPoly(ctr, 6, r-1, 30, rl.Magenta)
}
rl.DrawText(string(c.letter), int32(c.x)-5, int32(c.y)-10, 32, rl.Black)
rl.DrawPolyExLines(pts[i], 7, rl.Black)
rl.DrawText(sChosen, 100, 525, 24, rl.Black)
rl.DrawText(lChosen, 100, 565, 24, rl.Black)
}
rl.EndDrawing()
}
rl.CloseWindow()
}

View file

@ -0,0 +1,108 @@
using Gtk.ShortNames, GtkReactive, Graphics, Cairo, Colors
mutable struct Hexagon
center::Point
radius::Int
letter::String
color::Colorant
end
const offset = 50
const hgt = 450
const wid = 400
const hcombdim = (rows = 5, cols = 4)
const randletters = reshape(string.(Char.(shuffle(UInt8('A'):UInt8('Z'))))[1:20], Tuple(hcombdim))
const win = Window("Honeycombs", wid, hgt)
const can = Canvas()
const honeycomb = Dict{Point, Hexagon}()
const chosen = Vector{String}()
function hexmat(p, rad)
shor = rad * 0.5
long = rad * sqrt(3.0) / 2.0
mat = reshape([shor, long, -shor, long, Float64(-rad), 0.0, -shor, -long, shor, -long, Float64(rad), 0.0], 2, 6)
[Point(mat[1, n] + p.x, mat[2, n] + p.y) for n in 1:6]
end
function whichclicked(clickpos)
centers = [c for c in keys(honeycomb)]
(maybeclicked, idx) = findmin(map(c -> sqrt((clickpos.x - c.x)^2 + (clickpos.y - c.y)^2), centers))
return maybeclicked < offset * sqrt(3) / 2.0 ? centers[idx] : nothing
end
whichtyped(ch) = (for (k, v) in honeycomb if v.letter == ch return k end end; nothing)
function hexagon(ctx, pos, rad, ltr, colr = colorant"yellow")
set_source(ctx, colr)
points = hexmat(pos, rad)
set_line_width(ctx, 4)
polygon(ctx, points)
close_path(ctx)
fill(ctx)
set_source(ctx, colorant"black")
polygon(ctx, points)
close_path(ctx)
stroke(ctx)
move_to(ctx, pos.x - (ltr == "I" ? 7 : 18), pos.y + 15)
set_source(ctx, colr == colorant"yellow" ? colorant"red" : colorant"black")
set_font_size(ctx, offset)
show_text(ctx, ltr)
Hexagon(pos, rad, ltr, colr)
end
hexagon(ctx, h::Hexagon) = hexagon(ctx, h.center, h.radius, h.letter, h.color)
function makehoneycomb(ctx)
centers = fill(Point(0, 0), hcombdim.rows, hcombdim.cols)
xdelta = 75.0
ydelta = 90.0
for i in 1:hcombdim.rows, j in 1:hcombdim.cols
center = Point((i - 1) * xdelta + offset, (j - 1) * ydelta + ((i - 1 ) % 2 + 1) * offset)
centers[i, j] = center
honeycomb[center] = hexagon(ctx, center, offset, randletters[i, j])
end
centers
end
@guarded draw(can) do widget
ctx = getgc(can)
if length(honeycomb) == 0
makehoneycomb(ctx)
else
map(c -> hexagon(ctx, honeycomb[c]), collect(keys(honeycomb)))
end
end
""" At entry to this function we have just found out what letter was chosen."""
function changecolor(colr)
h = honeycomb[colr]
h.color = colorant"violet"
hexagon(getgc(can), h)
reveal(win, true)
push!(chosen, h.letter)
if all(map(k -> honeycomb[k].color == colorant"violet", collect(keys(honeycomb))))
println("All hexagons ($chosen, and the last letter was $(chosen[end])) have been chosen. Exiting.")
exit(0)
end
end
signal_connect(win, "key-press-event") do widget, event
if (whichhexgon = whichtyped(string(uppercase(Char(event.keyval))))) != nothing
changecolor(whichhexgon)
end
end
can.mouse.button1press = @guarded (widget, event) -> begin
if (whichhexgon = whichclicked(Point(event.x, event.y))) != nothing
changecolor(whichhexgon)
end
end
push!(win, can)
show(can)
condition = Condition()
endit(w) = notify(condition)
signal_connect(endit, win, :destroy)
show(win)
wait(condition)
exit()

View file

@ -0,0 +1,91 @@
import java.awt.{BasicStroke, BorderLayout, Color, Dimension,
Font, FontMetrics, Graphics, Graphics2D, Point, Polygon, RenderingHints}
import java.awt.event.{KeyAdapter, KeyEvent, MouseAdapter, MouseEvent}
import javax.swing.{JFrame, JPanel}
import scala.math.{Pi, cos, sin}
object Honeycombs extends App {
private val (letters, x1, y1, x2, y2, h, w) = ("LRDGITPFBVOKANUYCESM", 150, 100, 225, 143, 87, 150)
private class HoneycombsPanel() extends JPanel {
private val comb: IndexedSeq[Hexagon] =
for {i <- 0 until 20
(x: Int, y: Int) =
if (i < 12) (x1 + (i % 3) * w, y1 + (i / 3) * h)
else (x2 + (i % 2) * w, y2 + ((i - 12) / 2) * h)
} yield Hexagon(x, y, w / 3, letters(i))
override def paintComponent(gg: Graphics): Unit = {
super.paintComponent(gg)
val g = gg.asInstanceOf[Graphics2D]
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
g.setFont(new Font("SansSerif", Font.BOLD, 30))
g.setStroke(new BasicStroke(3))
comb.foreach(_.draw(g))
}
case class Hexagon(x: Int, y: Int, halfWidth: Int, letter: Char,
var hasBeenSelected: Boolean = false) extends Polygon {
private val (baseColor, selectedColor) = (Color.yellow, Color.magenta)
def setSelected(): Unit = hasBeenSelected = true
def draw(g: Graphics2D): Unit = {
val fm: FontMetrics = g.getFontMetrics
val (asc, dec) = (fm.getAscent, fm.getDescent)
def drawCenteredString(g: Graphics2D, s: String): Unit = {
val x: Int = bounds.x + (bounds.width - fm.stringWidth(s)) / 2
val y: Int = bounds.y + (asc + (bounds.height - (asc + dec)) / 2)
g.drawString(s, x, y)
}
g.setColor(if (hasBeenSelected) selectedColor else baseColor)
g.fillPolygon(this)
g.setColor(Color.black)
g.drawPolygon(this)
g.setColor(if (hasBeenSelected) Color.black else Color.red)
drawCenteredString(g, letter.toString)
}
for (i <- 0 until 6)
addPoint((x + halfWidth * cos(i * Pi / 3)).toInt, (y + halfWidth * sin(i * Pi / 3)).toInt)
getBounds
}
addKeyListener(new KeyAdapter() {
override def keyPressed(e: KeyEvent): Unit = {
val key = e.getKeyChar.toUpper
comb.find(_.letter == key).foreach(_.setSelected())
repaint()
}
})
addMouseListener(new MouseAdapter() {
override def mousePressed(e: MouseEvent): Unit = {
val mousePos: Point = e.getPoint
comb.find(h => h.contains(mousePos)).foreach(_.setSelected())
repaint()
}
})
setBackground(Color.white)
setPreferredSize(new Dimension(600, 500))
setFocusable(true)
requestFocus()
}
new JFrame("Honeycombs") {
add(new HoneycombsPanel(), BorderLayout.CENTER)
pack()
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE)
setLocationRelativeTo(null)
setResizable(false)
setVisible(true)
}
}