Inhalt:

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.

Beispiel, eines Würfelspiels

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.

Würfel mit Highlight

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:

Pythagoras in der Detektion ob ein Punkt zum Kreis gehört

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:Wenn der Mauszeiger im Kreis ist erscheint <<On Target!!>> in der Konsole, zusammen mit dem Zählerstand. Kommentiert man die Zeile ohne die Typänderung (uint16 -> int) aus dann ergeben sich falsch positive Werte (falsch negative natürlich auch).

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()
	}
}

One thought on “Würfel implementieren in Go

Comments are closed.