Inhalt:
- Implementierung der Würfel in Go
- Graphische Darstellung des Würfels
- Vervollständigen des Interfaces
- Implementierung von Platzhaltern und Farben für alle Würfel
- Würfel mit Mauszeiger bedienen
- Code (soweit er im Moment ist)
Damit man meinen Ausführungen folgen kann, ist es notwendig, dass man sich zum einen Go installiert, dann den Editor Geany und zu guter Letzt sich auch noch die Pakete besorgt, die leider mein Dozent Herr Schmidt geschrieben hat. Das einfachere von beiden Paketen, dass man braucht um die Programme so wie ich sie geschrieben habe zu benutzen, ist auf das gfx-Paket zuzugreifen.
Da Herr Schmidt den Link da zu ins Netz gestellt hat, denke ich ist es nicht weiter dramatisch, wenn ich es einfach hier verlinke. Es gibt zwei Versionen, wenn ich noch nichts geändert hat. Es gibt gfx (Linux und Windows) und es gibt gfx2 (Windows 10). Das einzige Paket, das euch dann noch fehlt ist ein Zufallszahlengenerator welcher in dem Go-Paket math/random steckt. Ich müsste Herrn Schmidt fragen, ob ich einfach sein Zufallszahlen-Paket weiter geben kann, das ist sicher etwas übersichtlicher.
Wenn dann alles richtig installiert ist, dann kann man schon einiges machen.
Implementierung der Würfel in Go
Nach diesem Video hat man das Grundgerüst eines Würfels, der ,wenn man Zufallszahlen generieren kann, immerhin schon würfeln kann.
Graphische Darstellung des Würfels
Das nächste Video zeigt, wie man den Würfel im Grafikfenster darstellen kann.
In dem Video benutze ich einfach eine kleine Datei, in der ich mein Code, für die Darstellung des Würfels ausprobiere. Den Code den ich dabei geschrieben habe findet ihr hier:
Graphik-Test
package main
import . "gfx"
func main () {
Fenster(1200,800)
Stiftfarbe(0,0,0)
var x,y,size uint16
x = 200
y = 200
size = 200
var wert uint
wert = 6
//Würfelkörper
Vollrechteck(x,y,size,size)
Vollkreis(x,y,size/10)
Vollkreis(x+size,y,size/10)
Vollkreis(x,y+size,size/10)
Vollkreis(x+size,y+size,size/10)
Vollrechteck(x-size/10,y,size/10,size)
Vollrechteck(x,y-size/10,size,size/10)
Vollrechteck(x+size,y,size/10+1,size)
Vollrechteck(x,y+size,size,size/10+1)
Stiftfarbe(255,255,255)
switch wert {
case 1:
Vollkreis(x+size/2,y+size/2,size/10)
case 2:
Vollkreis(x+size/5,y+size/5,size/10)
Vollkreis(x+size*4/5,y+size*4/5,size/10)
case 3:
Vollkreis(x+size/2,y+size/2,size/10)
Vollkreis(x+size/5,y+size/5,size/10)
Vollkreis(x+size*4/5,y+size*4/5,size/10)
case 4:
Vollkreis(x+size/5,y+size/5,size/10)
Vollkreis(x+size*4/5,y+size*4/5,size/10)
Vollkreis(x+size/5,y+size*4/5,size/10)
Vollkreis(x+size*4/5,y+size/5,size/10)
case 5:
Vollkreis(x+size/2,y+size/2,size/10)
Vollkreis(x+size/5,y+size/5,size/10)
Vollkreis(x+size*4/5,y+size*4/5,size/10)
Vollkreis(x+size/5,y+size*4/5,size/10)
Vollkreis(x+size*4/5,y+size/5,size/10)
case 6:
Vollkreis(x+size/5,y+size/5,size/10)
Vollkreis(x+size*4/5,y+size*4/5,size/10)
Vollkreis(x+size/5,y+size*4/5,size/10)
Vollkreis(x+size*4/5,y+size/5,size/10)
Vollkreis(x+size*4/5,y+size/2,size/10)
Vollkreis(x+size/5,y+size/2,size/10)
}
TastaturLesen1()
}
Jetzt kann man schon einiges mit dem Würfel anstellen, den wir Programmiert haben.
Es fehlen aber noch die anderen Würfel, die man so kaufen kann:
- Münze (zweiseitig)
- Tetraeder (vierseitig)
- Oktaeder (achtseitig)
- Dekaeder (zehnseitig)
- Dodekaeder (zwölfseitig)
- Ikosaeder (zwanzigseitig)
Diese müssen noch mithilfe des gfx-Pakets modelliert werden, so dass wirklich sämtliche Würfel zur Verfügung stehen.
Eure Ergebnisse könnt ihr mir unter naso@explain-it-arium.de zuschicken. Ich arbeite sie dann ein.
Ich habe gerade gesehen, dass es auch noch 100 würfel in 10er Schritten gibt. Das müsste man noch entsprechend integrieren, wenn man so etwas möchte.
Vervollständigen des Interfaces
Das nächste Video beschäftigt sich mit dem Interface, denn der arme Nutzer hat zwar ein Interface, hat aber gar keine Ahnung wie er es nutzen soll, oder was genau passiert, wenn er eine der Funktionen aufruft. Daher wird es nun Zeit sich mit dem Interface weiter auseinander zu setzen.
In dem Video geht es speziel darum, wie sich das Interface ändern muss, wenn man Änderungen an der SetzeWert-Funktion durchführt um zu verdeutlichen, wie man Voraussetzung und Ergebnis/Effekt richtig notiert.
Auch hier ist das Interface noch nicht vollständig. Bitte auch hier eure Version des Interfaces zu mir schicken (naso@explain-it-arium.de).
Implementierung von Platzhaltern und Farben für alle Würfel
In dem nächsten Video geht es um die Implementierung von Platzhaltern (genannt Schatten) für alle Würfel, da die bisherige Implementierung dies nur für die sechsseitigen Würfel zugelassen hat. Ganz neben bei wird den Würfeln noch Farbe verpasst. Dies soll euch zeigen, dass solch eine Implementierung nicht in Stein gemeißelt ist, sondern von euch je nach bedarf verändert werden kann.
In dem Video dachte ich, dass ich mit dem Würfel fertig wäre, aber eine wichtige Eigenschaft fehlt noch.
Würfel mit Mauszeiger bedienen
Für ein richtiges graphisches User-Interface braucht es Clicki-Bunti. Bunti haben wir schon, auch wenn es da sicher noch einige Wünsch gibt. Es fehlt das Clicki. Daher habe ich jetzt entsprechend die Implementierung um die Bedienung mit dem Mauszeiger erweitert und ein Highlighting (Hover-Funktion) gibt es auch.
In dem Video zeige ich euch wie dies implementiert ist. Ich verwende die Draw-Funktion als Seter-Funktion für die Position und Größe des Würfels. Es gibt entsprechende Variablen in denen diese im Würfel gespeichert werden. Zusätzlich bekommen die Würfel noch eine Highlight-Farbe und eine Variable, ob ein Highlight gewünscht ist.
Das schließt die Funktionen des Würfels ab.
Um die Bedienung mit der Maus zu ermöglichen ist es nötig zu testen, ob der Punkt des Mauszeigers auf den gezeichneten Objekten liegt, in diesem Fall der Würfel. Die Idee ist es, da der Würfel aus vielen Teilen besteht, jedes einzelne zu testen und wenn der Mauszeiger auf einem von ihnen landet, dann ist er auf dem Würfel.
Test für ein Rechteck
Der zu testende Punkt muss sich zwischen den x- und y-Koordinaten befinden, die das Rechteck aufspannt. Da in gfx ein Rechteck gegeben ist aus dem Punkt der linken oberen Ecke und der Breite und Höhe des Rechtecks ergibt sich:
x-Rechteck <= x-punkt <= x-Rechteck+Breite
&&
y-Rechteck <= y-Punkt <= y-Rechteck+Höhe
Im eigentlichen Code muss jede Aussage einzeln getestet werden.
Test für den Kreis
Beim Kreis funktioniert es ähnlich. Man bildet die Differenz der jeweiligen Koordinaten der Punkte und wenn der Abstand kleiner ist als der Radius, dann ist der Punkt im Kreis. Um die Distanz direkt zu ermitteln zwischen den beiden Punkten (Mittelpunkt des Kreises und der zu testende Punkt) bräuchte man den Sinus oder den Cosinus. Das sind Berechnung, die für den Computer aufwendig sind und lange dauern. Einfacher und schnelle ist es sich des alten Satz des Pythagoras zu entsinnen.
(a*a) + (b*b) = (c*c)
Wobei a = der Differenz der x-Koordinaten der beiden Punkte ist, b = der Differenz der beiden y-Koordinaten und c = dem Radius des Kreises ist. Da wir nicht genau den Rand treffen wollen, sonder uns nur interessiert ob es kleiner gleich des Radius ist ist die eigentliche Formel für den Test folgende:
Wie man sehen kann wird durch die Differenzen (dx und dy) ein rechtwinkliges Dreieck aufgespannt, bei dem die Hypotenuse genau der Distanz zwischen den beiden Punkten entspricht. Da es sich um ein rechtwinkliges Dreieck handelt, können wir auf den Satz von Pythagoras zurückgreifen und so unser Problem lösen.
Ein kleines Problem ergibt sich, dadurch, dass die Koordinaten in uint16 vorliegen. Daher sind weder Werte, die größer sind als 65535 nicht möglich (Roll over), auch werden Rechnungen, bei denen negative Zahlen entstehen falsch interpretiert. Daher sind alle Zahlen in int um zu wandeln (Typumwandlung – int(uint16)) dann hat man auch keine Probleme mit dem Test.
Hier ein kleines Programm zum selber ausprobieren:
Kreis-Test-Programm
package main
import (. "gfx"
"fmt")
func main () {
Fenster (1200,800)
var x,y,size uint16
x = 600
y = 400
size = 100
Stiftfarbe(255,0,0)
Vollkreis(x,y,size)
//MausLesen1 () (taste uint8, status int8, mausX, mausY uint16)
var xposition,yposition uint16
var counter int
for {
if xposition <= 50 && yposition <= 50 && xposition !=0 && yposition !=0 {
break
}
_,_,xposition,yposition = MausLesen1()
if (int(xposition)-int(x))*(int(xposition)-int(x))+((int(yposition)-int(y))*(int(yposition)-int(y))) <= int(size) * int(size) {
//if ((xposition)-(x))*((xposition)-(x))+(((yposition)-(y))*((yposition)-(y))) <= (size) * (size) {
fmt.Println("On Target!! ", counter)
counter++
}
}
}
Die Testdatei, um die Bedienung mit dem Mauszeiger zu testen befindet sich ganz unten – Mauszeigertest.
Code (soweit er im Moment ist)
Interface
package wuerfel
type Wuerfel interface {
//Vor.: -
//Erg.:Ein Würfel mit der gegeben Seitenzahl ist zurückgegeben.
//Für den Schatten eines Würfels geben Sie die Seitenzahl 0 an und dann die Seitenzahl des Würfels für den der Schatten sein soll.
//Eff.: Würfelwert ist 0 (entspricht ungewürfelt).
//New (seiten,schatten uint)
GibWert () uint
GibSeiten () uint
//Vor.: -
//Erg.: Die Farbe des Würfels in r,g,b ist zurückgegeben.
GibWuerfelFarbe () (r,g,b uint8)
//Vor.: -
//Erg.: Die Farbe der Punkte in r,g,b ist zurückgegeben.
GibPunktFarbe () (r,g,b uint8)
GibPosition () (x,y uint16)
GibGroesse () (size uint16)
GibHighlightFarbe() (r,g,b uint8)
SetzeSeiten (seiten uint)
//Vor.: -
//Eff.: Würfelwert besitzt den gegeben Wert, wenn Wert <= Seitenzahl des Würfels ist,
//andernfalls passiert nichts.
SetzeWert (wert uint)
//Vor.: -
//Eff.: Würfelwert besitzt den gegeben Wert, wenn Wert <= Seitenzahl des Würfels ist,
//wird der Wert des Würfels maximal (Seitenzahl).
SetzeWertb (wert uint)
//Vor.: Wert <= Seitenzahl des Würfels
//Eff.: Würfelwert besitzt den gegeben Wert.
SetzeWertc (wert uint)
//Vor.: -
//Eff.: Der Würfel besitzt die mit r,g,b gegebene Farbe.
SetzeWuerfelFarbe (r,g,b uint8)
//Vor.: -
//Eff.: Die Punkte besitzten die mit r,g,b gegebene Farbe.
SetzePunktFarbe (r,g,b uint8)
SetzeHighlightFarbe (r,g,b uint8)
Zuruecksetzen ()
SetzeHighlight (highlight bool)
String () string
Wuerfeln ()
PunktgehörtzumWuerfel (xp,yp uint16) bool
Draw(x,y,size uint16)
}
Implementierung
package wuerfel
import (. "zufallszahlen"
"fmt"
. "gfx"
)
type data struct {
seiten uint
wert uint
schatten uint
wr,wg,wb uint8
pr,pg,pb uint8
hr,hg,hb uint8
x,y,size uint16
highlight bool
}
func New(seiten, schatten uint) *data {
var w *data
w = new(data)
(*w).seiten = seiten
(*w).schatten = schatten
(*w).wr,(*w).wg,(*w).wb = 255,255,255
(*w).pr,(*w).pg,(*w).pb = 0,0,0
(*w).hr,(*w).hg,(*w).hb = 255,0,0
//(*w).wert = 0 //Alle auskommentierte Zeilen werden von Go automatisch mit Null initialisiert
//(*w).x = 0 //Position und Größe wird über die Draw-Funktion gesteuert
//(*w).y = 0
//(*w).size = 0
//(*w).highlight = false
return w
}
//Geter-Funktionen
func (w *data) GibWert () uint {
return (*w).wert
}
func (w *data) GibSeiten () uint {
return (*w).seiten
}
func (w *data) GibWuerfelFarbe () (r,g,b uint8) {
return (*w).wr,(*w).wg,(*w).wb
}
func (w *data) GibPunktFarbe () (r,g,b uint8) {
return (*w).pr,(*w).pg,(*w).pb
}
func (w *data) GibPosition () (x,y uint16) {
return (*w).x,(*w).y
}
func (w *data) GibGroesse () (size uint16) {
return (*w).size
}
func (w *data) GibHighlightFarbe() (r,g,b uint8) {
return (*w).hr,(*w).hg,(*w).hb
}
//Seter-Funktionen
func (w *data) SetzeWert (wert uint) { //kein Effekt bei Falscheingabe
if wert <= (*w).seiten {
(*w).wert = wert
}
}
func (w *data) SetzeWertb (wert uint) { //bei Falscheingabe wird Wert maximal
if wert <= (*w).seiten {
(*w).wert = wert
} else {
(*w).wert = (*w).seiten
}
}
func (w *data) SetzeWertc (wert uint) { //bei Falscheingabe bricht das Programm mit einer Panic ab
if wert <= (*w).seiten {
(*w).wert = wert
} else {
panic ("Gewünster Wert größer als die Seitenzahl des Würfels!!!")
}
}
func (w *data) SetzeSeiten (seiten uint) {
(*w).seiten = seiten
}
func (w *data) SetzeWuerfelFarbe (r,g,b uint8) {
(*w).wr = r
(*w).wg = g
(*w).wb = b
}
func (w *data) SetzePunktFarbe (r,g,b uint8) {
(*w).pr = r
(*w).pg = g
(*w).pb = b
}
func (w *data) SetzeHighlightFarbe (r,g,b uint8) {
(*w).hr = r
(*w).hg = g
(*w).hb = b
}
func (w *data) Zuruecksetzen () {
(*w).wert = 0
}
func (w *data) SetzeHighlight (highlight bool) {
(*w).highlight = highlight
}
//Es gibt keine Seter-Funktion für die Position oder die Größe, da dies die Draw-Funktion mit ihrer Hilfsfunktion wasDrawnAs übernimmt!!!
func (w *data) String () string {
var erg string
erg = erg + fmt.Sprint("[")
erg = erg + fmt.Sprint((*w).wert)
erg = erg + fmt.Sprint("]")
return erg
}
func (w *data) Wuerfeln () {
Randomisieren()
if (*w).seiten>0{
(*w).wert = uint(Zufallszahl(1,int64((*w).seiten)))
}
}
//Eine etwas aufwändigere Funktion, da wir hier alle programmierten Seitenanzahlen abdecken müssen, und diese alle einzeln, wie in der Draw-Funktion programmiert werden müssen.
func (w *data) PunktgehörtzumWuerfel (xp,yp uint16) bool {
var xw,yw,size uint16
xw = (*w).x
yw = (*w).y
size = (*w).size
switch (*w).seiten {
case 0:
switch (*w).schatten {
case 2:
case 4:
case 6:
//Vollrechteck(x,y,size,size)
if xp >= xw && xp <= xw + size && yp >= yw && yp <= yw + size {
return true
}
//Vollrechteck(x-size/10,y,size/10,size)
if xp >= xw-size/10 && xp <= xw && yp >= yw && yp <= yw + size {
return true
}
//Vollrechteck(x,y-size/10,size,size/10)
if xp >= xw && xp <= xw + size && yp >= yw-size/10 && yp <= yw {
return true
}
//Vollrechteck(x+size,y,size/10+1,size)
if xp >= xw+size && xp <= xw+size+size/10+1 && yp >= yw && yp <= yw + size {
return true
}
//Vollrechteck(x,y+size,size,size/10+1)
if xp >= xw && xp <= xw + size && yp >= yw+size && yp <= yw+size+size/10+1 {
return true
}
//Vollkreis(x,y,size/10) - hier wird der Satz des Pytagoras angewendet: Achtung!! bei den Variablen handelt es sich um uint16-Werte, für die Berechnung wird aber int benötigt!!!
if (int(xp)-int(xw))*(int(xp)-int(xw))+(int(yp)-int(yw))*(int(yp)-int(yw)) <= (int(size)/10) * (int(size)/10) {
return true
}
//Vollkreis(x,y+size,size/10)
if (int(xp)-int(xw))*(int(xp)-int(xw))+(int(yp)-int(yw+size))*(int(yp)-int(yw+size)) <= (int(size)/10) * (int(size)/10) {
return true
}
//Vollkreis(x+size,y,size/10)
if (int(xp)-int(xw+size))*(int(xp)-int(xw+size))+(int(yp)-int(yw))*(int(yp)-int(yw)) <= (int(size)/10) * (int(size)/10) {
return true
}
//Vollkreis(x+size,y+size,size/10)
if (int(xp)-int(xw+size))*(int(xp)-int(xw+size))+(int(yp)-int(yw+size))*(int(yp)-int(yw+size)) <= (int(size)/10) * (int(size)/10) {
return true
}
case 8:
case 12:
case 20:
default:
}
case 2:
case 4:
case 6:
//Vollrechteck(x,y,size,size)
if xp >= xw && xp <= xw + size && yp >= yw && yp <= yw + size {
return true
}
//Vollrechteck(x-size/10,y,size/10,size)
if xp >= xw-size/10 && xp <= xw && yp >= yw && yp <= yw + size {
return true
}
//Vollrechteck(x,y-size/10,size,size/10)
if xp >= xw && xp <= xw + size && yp >= yw-size/10 && yp <= yw {
return true
}
//Vollrechteck(x+size,y,size/10+1,size)
if xp >= xw+size && xp <= xw+size+size/10+1 && yp >= yw && yp <= yw + size {
return true
}
//Vollrechteck(x,y+size,size,size/10+1)
if xp >= xw && xp <= xw + size && yp >= yw+size && yp <= yw+size+size/10+1 {
return true
}
//Vollkreis(x,y,size/10) - hier wird der Satz des Pytagoras angewendet: Achtung!! bei den Variablen handelt es sich um uint16-Werte, für die Berechnung wird aber int benötigt!!!
if (int(xp)-int(xw))*(int(xp)-int(xw))+(int(yp)-int(yw))*(int(yp)-int(yw)) <= (int(size)/10) * (int(size)/10) {
return true
}
//Vollkreis(x,y+size,size/10)
if (int(xp)-int(xw))*(int(xp)-int(xw))+(int(yp)-int(yw+size))*(int(yp)-int(yw+size)) <= (int(size)/10) * (int(size)/10) {
return true
}
//Vollkreis(x+size,y,size/10)
if (int(xp)-int(xw+size))*(int(xp)-int(xw+size))+(int(yp)-int(yw))*(int(yp)-int(yw)) <= (int(size)/10) * (int(size)/10) {
return true
}
//Vollkreis(x+size,y+size,size/10)
if (int(xp)-int(xw+size))*(int(xp)-int(xw+size))+(int(yp)-int(yw+size))*(int(yp)-int(yw+size)) <= (int(size)/10) * (int(size)/10) {
return true
}
case 8:
case 12:
case 20:
}
return false
}
//Hilfsfunktionen zur Veränderung von Größe und Position
func (w *data) wasDrawnAs (x,y,size uint16) {
(*w).x = x
(*w).y = y
(*w).size = size
}
func (w *data) Draw (x,y,size uint16) {
var zeilen,spalten uint16 //Fragt die Zeilen und Spalten des Grafikfensters ab spalten=pixel in x-Achse/Breite, zeilen = pixel in y-Achse/Höhe
if FensterOffen() {
zeilen = Grafikzeilen()
spalten = Grafikspalten()
}
w.wasDrawnAs(x,y,size) //Schreibt die Werte von x,y und size in den Würfel; s. Hilfsfunktion
var wr,wg,wb,pr,pg,pb,hr,hg,hb uint8
wr,wg,wb = w.GibWuerfelFarbe()
pr,pg,pb = w.GibPunktFarbe()
hr,hg,hb = w.GibHighlightFarbe()
switch (*w).seiten {
case 0:
switch (*w).schatten {
case 6:
if (*w).highlight {
Stiftfarbe(hr,hg,hb)
Vollrechteck(x-5,y-5,size+10,size+10)
Vollrechteck(x-5-(size+10)/10,y-5,(size+10)/10,size+10)
Vollrechteck(x-5,y-5 -(size+10)/10,size+10,(size+10)/10)
Vollrechteck(x-5+size+10,y-5,(size+10)/10+1,size+10)
Vollrechteck(x-5,y-5+size+10,size+10,(size+10)/10+1)
Vollkreis(x-5,y-5,(size+10)/10)
Vollkreis(x-5,y-5+size+10,(size+10)/10)
Vollkreis(x-5+size+10,y-5,(size+10)/10)
Vollkreis(x-5+size+10,y-5+size+10,(size+10)/10)
}
if x+size+size/10<spalten && y+size+size/10<zeilen && x-size/10>=1 && y-size/10>=1{
Stiftfarbe(120,120,120)
Vollrechteck(x,y,size,size)
Vollrechteck(x-size/10,y,size/10,size)
Vollrechteck(x,y-size/10,size,size/10)
Vollrechteck(x+size,y,size/10+1,size)
Vollrechteck(x,y+size,size,size/10+1)
Vollkreis(x,y,size/10)
Vollkreis(x,y+size,size/10)
Vollkreis(x+size,y,size/10)
Vollkreis(x+size,y+size,size/10)
}
}
case 2: //Münze
case 4: //Tetraeder-Würfel
case 6: //normaler 6-seitiger Würfel
if (*w).highlight {
Stiftfarbe(hr,hg,hb)
Vollrechteck(x-5,y-5,size+10,size+10)
Vollrechteck(x-5-(size+10)/10,y-5,(size+10)/10,size+10)
Vollrechteck(x-5,y-5 -(size+10)/10,size+10,(size+10)/10)
Vollrechteck(x-5+size+10,y-5,(size+10)/10+1,size+10)
Vollrechteck(x-5,y-5+size+10,size+10,(size+10)/10+1)
Vollkreis(x-5,y-5,(size+10)/10)
Vollkreis(x-5,y-5+size+10,(size+10)/10)
Vollkreis(x-5+size+10,y-5,(size+10)/10)
Vollkreis(x-5+size+10,y-5+size+10,(size+10)/10)
}
Stiftfarbe(pr,pg,pb)
if x+size+size/10<spalten && y+size+size/10<zeilen && x-size/10>=1 && y-size/10>=1 {
Stiftfarbe(wr,wg,wb)
Vollrechteck(x,y,size,size)
Vollrechteck(x-size/10,y,size/10,size)
Vollrechteck(x,y-size/10,size,size/10)
Vollrechteck(x+size,y,size/10+1,size)
Vollrechteck(x,y+size,size,size/10+1)
Vollkreis(x,y,size/10)
Vollkreis(x,y+size,size/10)
Vollkreis(x+size,y,size/10)
Vollkreis(x+size,y+size,size/10)
Stiftfarbe(pr,pg,pb)
switch (*w).wert {
case 1:
Vollkreis(x+size/2,y+size/2,size/10)
case 2:
Vollkreis(x+size/5,y+size/5,size/10)
Vollkreis(x+size*4/5,y+size*4/5,size/10)
case 3:
Vollkreis(x+size/5,y+size/5,size/10)
Vollkreis(x+size/2,y+size/2,size/10)
Vollkreis(x+size*4/5,y+size*4/5,size/10)
case 4:
Vollkreis(x+size/5,y+size/5,size/10)
Vollkreis(x+size*4/5,y+size*4/5,size/10)
Vollkreis(x+size/5,y+size*4/5,size/10)
Vollkreis(x+size*4/5,y+size/5,size/10)
case 5:
Vollkreis(x+size/5,y+size/5,size/10)
Vollkreis(x+size/2,y+size/2,size/10)
Vollkreis(x+size*4/5,y+size*4/5,size/10)
Vollkreis(x+size*4/5,y+size/5,size/10)
Vollkreis(x+size/5,y+size*4/5,size/10)
case 6:
Vollkreis(x+size/5,y+size/5,size/10)
Vollkreis(x+size/5,y+size/2,size/10)
Vollkreis(x+size*4/5,y+size/2,size/10)
Vollkreis(x+size*4/5,y+size*4/5,size/10)
Vollkreis(x+size*4/5,y+size/5,size/10)
Vollkreis(x+size/5,y+size*4/5,size/10)
}
}
case 8: //Oktaeder
case 12: //Dodecaeder
case 20: //Icosanoeder
default: //
}
}
Würfeltest-Datei
Hier ist der Beginn der Programmierung eines Spiels genannt 10000. Es ist beileibe noch nicht fertig und so wie es ist Work-in-progress, aber es hilft vielleicht einigen weiter, die ähnliche Probleme haben.
Viel Spaß mit den Code.
P.S.: Wenn ihr etwas tolles draus gemacht habt, dann zeigt doch mal eure Programme her.
package main
import ("wuerfel"
"fmt"
"gfx"
//"time"
//"strconv"
)
func main () {
//var anzahlSpieler string
//fmt.Print("Geben Sie bitte die Anzahl der Spieler an: ")
//fmt.Scanln(&anzahlSpieler)
//nS,_:=strconv.Atoi(anzahlSpieler)
//var namen []string
//punktel:= make([]int,nS)
//for i:=0;i<nS;i++{
//fmt.Print("Bitte geben den Sie den Namen für den ",i+1,". Spieler ein: ")
var gezählt [6]uint
var punkteStand,punkteRunde int
var anzahlRunden int
new:
var w1,w2,w3,w4,w5,w6,p1,p2,p3,p4,p5,p6 wuerfel.Wuerfel
w1 = wuerfel.New(6,0)
w2 = wuerfel.New(6,0)
w3 = wuerfel.New(6,0)
w3.SetzeWuerfelFarbe(0,255,0)
w3.SetzePunktFarbe(0,0,255)
w4 = wuerfel.New(6,0)
w5 = wuerfel.New(6,0)
w6 = wuerfel.New(6,0)
p1 = wuerfel.New(0,6)
p2 = wuerfel.New(0,6)
p3 = wuerfel.New(0,6)
p4 = wuerfel.New(0,6)
p5 = wuerfel.New(0,6)
p6 = wuerfel.New(0,6)
gfx.Fenster(1000,800)
gfx.Stiftfarbe(47,186,51)
gfx.Vollrechteck(1,1,999,798)
var wliste,pliste []wuerfel.Wuerfel
wliste = append(wliste,w1,w2,w3,w4,w5,w6)
pliste = append(pliste,p1,p2,p3,p4,p5,p6)
outer:
for {
for i:=0;i<len(wliste);i++{
wliste[i].Wuerfeln()
wliste[i].Draw(uint16((i+1)*100)-50,50,60)
pliste[i].Draw(900,uint16((i+1)*100)+50,60)
}
var taste,tiefe uint16
var gedrueckt uint8
var a bool
inner:
for {
taste,gedrueckt,tiefe = gfx.TastaturLesen1()
var b rune
b = gfx.Tastaturzeichen(taste,tiefe)
if gedrueckt==0{
switch b {
case 'q':
break outer
case '1':
if gezählt[0]==0{
wliste,pliste=tauschen(1,wliste,pliste)
}
case '2':
if gezählt[1]==0{
wliste,pliste=tauschen(2,wliste,pliste)
}
case '3':
if gezählt[2]==0{
wliste,pliste=tauschen(3,wliste,pliste)
}
case '4':
if gezählt[3]==0{
wliste,pliste=tauschen(4,wliste,pliste)
}
case '5':
if gezählt[4]==0{
wliste,pliste=tauschen(5,wliste,pliste)
}
case '6':
if gezählt[5]==0{
wliste,pliste=tauschen(6,wliste,pliste)
}
case 'w':
if punkte(pliste,gezählt)!=0 || a {
a = false
punkteRunde = punkteRunde+punkte(pliste,gezählt)
fmt.Println("Neuerpunktestand in dieser Runde: ",punkteRunde)
for i:=0;i<len(pliste);i++{
if pliste[i].GibSeiten()!=0{
gezählt[i] = 1
}
}
for i:=0;i<len(wliste);i++{
wliste[i].Wuerfeln()
}
break inner
}
case 'n':
if punkte(pliste,gezählt)!=0 || a {
a = false
punkteRunde = punkteRunde+punkte(pliste,gezählt)
punkteStand = punkteStand+punkteRunde
}
if !alleWürfel(gezählt){
anzahlRunden = anzahlRunden + 1
}
for i:=0;i<len(gezählt);i++{
gezählt[i] = 0
}
punkteRunde = 0
fmt.Println("Punktestand im Spiel bis jetzt: ",punkteStand)
if punkteStand >= 10000 {
fmt.Println("Sie haben ",punkteStand," in ",anzahlRunden," Runden erreicht. Herzlichen Glückwunsch!")
break outer
}
goto new
case 'a':
var index1,index2 int
for i:=0;i<len(pliste);i++{
if pliste[i].GibWert()==5 {
index1 = i
for j:=i+1;j<len(pliste);j++{
if pliste[j].GibWert()==5{
index2 = j
pliste[index1].SetzeWert(1)
pliste[index2].SetzeWert(0)
wliste,pliste = tauschen(index2+1,wliste,pliste)
if gezählt[index1]==1 && gezählt[index2]==1{
gezählt[index2] = 0
} else if gezählt[index1]==1 && gezählt[index2]==0{
punkteRunde = punkteRunde+50
} else if gezählt[index1]==0 && gezählt[index2]==1{
punkteRunde = punkteRunde+50
gezählt[index1] = 1
gezählt[index2] = 0
} else {
punkteRunde = punkteRunde+100
gezählt[index1] = 1
}
a = true
break
}
}
break
}
}
default:
}
for i:=0;i<len(wliste);i++{
wliste[i].Draw(uint16((i+1)*100)-50,50,60)
pliste[i].Draw(900,uint16((i+1)*100)+50,60)
}
}
}
}
}
func tauschen (zahl int,l1,l2 []wuerfel.Wuerfel) ([]wuerfel.Wuerfel,[]wuerfel.Wuerfel) {
l1[zahl-1],l2[zahl-1]=l2[zahl-1],l1[zahl-1]
return l1,l2
}
func punkte (pliste []wuerfel.Wuerfel,gezählt [6]uint) int { //Berechnet die Punke in dem zuerst die Anzahl von jedem Würfeltyp zählt und anschließend die Punkte berechnet
var erg int
var z1,z2,z3,z4,z5,z6 int
for i:=0;i<len(pliste);i++{
if gezählt[i]==0{
switch pliste[i].GibWert() {
case 1:
z1=z1+1
case 2:
z2=z2+1
case 3:
z3=z3+1
case 4:
z4=z4+1
case 5:
z5=z5+1
case 6:
z6=z6+1
}
}
}
erg = z1/3*1000+z1%3*100+z2/3*200+z3/3*300+z4/3*400+z5/3*500+z5%3*50+z6/3*600
return erg
}
func alleWürfel (gezählt [6]uint) bool {
for i:=0;i<len(gezählt);i++{
if gezählt[i]==0{
return false
}
}
return true
}
Mauszeigertest
Hier ist ein kleines Testprogramm, mit dem man die Bedienung der Würfel mit Mauszeiger testen kann.
Viel Spaß!
package main
import ("wuerfel"
"gfx"
"fmt"
)
func main () {
gfx.Fenster(1200,800)
var w1,p1 wuerfel.Wuerfel
w1 = wuerfel.New(6,0)
p1 = wuerfel.New(0,6)
w1.SetzeHighlightFarbe(17, 26, 189)
gfx.Stiftfarbe(0,255,0)
gfx.Vollrechteck(1,1,1198,798)
var x,y,size uint16
x = 350
y = 350
size = 100
//MausLesen1 () (taste uint8, status int8, mausX, mausY uint16)
var xposition,yposition uint16
var taste uint8
var status int8
var counter int
var liste []wuerfel.Wuerfel
liste = append(liste,w1,p1)
for i:=0;i<len(liste);i++{
liste[i].Draw(x*uint16(i+1),y,size)
}
for {
if xposition <= 50 && yposition <= 50 && xposition !=0 && yposition !=0 {
break
}
taste,status,xposition,yposition = gfx.MausLesen1()
if w1.PunktgehörtzumWuerfel(xposition,yposition) {
w1.SetzeHighlight(true)
if taste == 1 && status == 1 {
w1.Wuerfeln()
counter++
fmt.Println("Wurf ",counter,": ",w1.GibWert())
}
} else {
w1.SetzeHighlight(false)
}
if p1.PunktgehörtzumWuerfel(xposition,yposition) {
p1.SetzeHighlight(true)
if taste == 1 && status == 1 {
liste[0],liste[1] = liste[1],liste[0]
}
} else {
p1.SetzeHighlight(false)
}
gfx.UpdateAus()
gfx.Stiftfarbe(255,255,255)
gfx.Cls()
gfx.Stiftfarbe(0,255,0)
gfx.Vollrechteck(1,1,1198,798)
for i:=0;i<len(liste);i++{
liste[i].Draw(x*uint16(i+1),y,size)
}
gfx.UpdateAn()
}
}
Pingback: Spielkarten implementieren in Go | Explain-It-Arium