[svn] r6044: nemerle/trunk/snippets/gon: . Game.n GnuGoPlayer.n Goban.n GtkGame.n Main.n Makefile doc-pl d...

malekith svnadmin at nemerle.org
Thu Dec 29 16:18:41 CET 2005


Log:
A GNUgo interface by Grzegorz Moskal.

Author: malekith
Date: Thu Dec 29 16:18:38 2005
New Revision: 6044

Added:
   nemerle/trunk/snippets/gon/   (props changed)
   nemerle/trunk/snippets/gon/Game.n
   nemerle/trunk/snippets/gon/GnuGoPlayer.n
   nemerle/trunk/snippets/gon/Goban.n
   nemerle/trunk/snippets/gon/GtkGame.n
   nemerle/trunk/snippets/gon/Main.n
   nemerle/trunk/snippets/gon/Makefile
   nemerle/trunk/snippets/gon/doc-pl/
   nemerle/trunk/snippets/gon/doc-pl/class.txt
   nemerle/trunk/snippets/gon/doc-pl/reusing.txt
   nemerle/trunk/snippets/gon/doc-pl/systemControl.txt
   nemerle/trunk/snippets/gon/doc-pl/uml.dia   (contents, props changed)
   nemerle/trunk/snippets/gon/gfx/
   nemerle/trunk/snippets/gon/gfx/bg2.jpg   (contents, props changed)
   nemerle/trunk/snippets/gon/gfx/black.png   (contents, props changed)
   nemerle/trunk/snippets/gon/gfx/horizontal.png   (contents, props changed)
   nemerle/trunk/snippets/gon/gfx/sblack.png   (contents, props changed)
   nemerle/trunk/snippets/gon/gfx/swhite.png   (contents, props changed)
   nemerle/trunk/snippets/gon/gfx/vertical.png   (contents, props changed)
   nemerle/trunk/snippets/gon/gfx/white.png   (contents, props changed)

Added: nemerle/trunk/snippets/gon/Game.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/gon/Game.n	Thu Dec 29 16:18:38 2005
@@ -0,0 +1,54 @@
+using Gon;
+
+namespace Gon {
+ /// Abstarkcyjna klasa reprezentujÄ
ca gracza.
+ public abstract class Player {
+ 	public name: string;
+	public color: Color;
+	/// Ustawia ruch.
+	///
+	/// Funkcja jeśli jest taka potrzeba powinna ustawiać
+	/// ruch na planszy, woĹ‚a siÄ™ jÄ
 z parametrami ruchu
+	/// przeciwnika, potrzebne przy grze z komputerem lub grze przez sieć.
+	virtual public SetMove(_i: int, _y: int) : void
+	{
+		
+	}
+	/// Pobierz ruch.
+	///
+	/// Funkcja pobiera ruch od gracz standardowo zwraca tzw. ruch 
+	/// pusty tj trĂłjkÄ™ (0,0,Color.Empty).
+	virtual public Get() : int*int*Color
+	{
+		(0,0, Color.Empty); 
+	}
+	/// Kkonstruktor gracza.
+	///
+	/// Funkcja bierze nazwÄ™ i kolor dla gracza.
+	public this (n: string, clr: Color)
+	{
+		name = n;
+		color = clr;
+	}
+ }
+ /// Abstrakcyjna klasa reprezentujÄ
ca grÄ™.
+ public abstract class Game {
+	public black: Player;
+ 	public white: Player;
+	public mutable current: Color;
+	public goban: Goban;
+
+//	public abstract Display(array[2, Color]) : void;
+	/// Konstruktor abstrakcyjnej gry go ;)
+	///
+	/// Funkcja bierze goban (plansze) i dwĂłch graczy.
+	public this(g: Goban, b: Player, w: Player)
+	{
+		black = b;
+		white = w;
+		goban = g;
+		current = Color.Black;
+	}
+ }
+
+}

Added: nemerle/trunk/snippets/gon/GnuGoPlayer.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/gon/GnuGoPlayer.n	Thu Dec 29 16:18:38 2005
@@ -0,0 +1,131 @@
+using Gon;
+using System;
+using Nemerle.IO;
+using System.IO;
+using System.Diagnostics;
+using System.ComponentModel;
+
+
+namespace Gon 
+{
+ /// Klasa Gnugoplayer - interfejs dla programu gnugo.
+ public class GnuGoPlayer: Player
+ {
+ 	process : Process;
+	writer : StreamWriter;
+	reader : StreamReader;
+	size : int;
+	mycolor : string;
+	hiscolor : string;
+	/// Wysłanie stringu.
+	///
+	/// Funkcja pisze na stdin gnugo podany string.
+	send(msg: string) : void
+	{
+               	writer.Write(msg + "\n");
+		printf("sending '%s'\n", msg);
+	}
+	
+	/// Pobranie współrzędnych ruch.
+	///
+	/// Funkcja czyta ze stdout gnugo ruch, jeśli program
+	/// zwrócił PASS, to funkcja zwraca (-2,-2,color),
+	/// w przeciwnym przypadku zwracany jest poprawny ruch.
+	override public Get() : int*int*Color
+	{
+		send(sprintf("genmove %s", mycolor));
+		mutable column = 'a';
+		mutable row = 0;
+		mutable i = 0;
+		mutable j = 0;
+
+		mutable s = reader.ReadLine();
+		printf("he = '%s'\n",s);
+		_ = reader.ReadLine();
+		if (s == "= PASS") 
+			(-2, -2, color);
+		else {
+			sscanf(s, "= %c%d", column, row);
+			i = column:>int - 65;
+			j = size - row;
+			(i, j, color);
+		}
+	}
+
+	/// Ustaw ruch przeciwnika.
+	///
+	/// Funkcja wysyła do gnugo ruch przeciwnika.
+	override public SetMove(i:int, j:int) : void
+	{
+		mutable c = 65 + i;
+		send(sprintf("play %s %c%d", hiscolor, c:>char, size - j));
+                _ = reader.ReadLine();
+		_ = reader.ReadLine();
+	}
+	/// Przygotuj gnugo.
+	///
+	/// Funkcja przygotowuje gnugo do gry :
+	/// ustawia rozmiar planszy, czysci ja i ustwia komi.
+	public Init() : void
+	{
+		System.Console.WriteLine ("init gnu god\n");
+//		send("protocol_version");
+		send(sprintf("boardsize %d", size));
+                _ = reader.ReadLine();
+		_ = reader.ReadLine();
+//		send("komi 5.00");
+		send("clear_board");
+                _ = reader.ReadLine();
+		_ = reader.ReadLine();
+	}
+	/// Konstruktor objektu GnuGoPlayer.
+	///
+	/// Opis argumentĂłw: s jest rozmiarem planszy, clr jest kolorem gracza,
+	/// path jest sciezka do programu obslugujacego GTP protocol,
+	/// a args to argumenty przekazane do tego programu.
+	/// Funkcja tworzy nowy proces i woła Init().
+ 	public this(s: int, clr: Color,  
+			path = "/usr/bin/gnugo", 
+			args = "--mode gtp --quiet --level 1")
+	{ 
+		base("GnuGo", clr);
+
+		size = s;
+		process = Process();
+		if (clr == Color.White) {
+			mycolor = "white";
+			hiscolor = "black";
+		} else {
+			mycolor = "black";
+			hiscolor = "white";
+		}
+			
+	        
+         	process.StartInfo.FileName = path;
+         	process.StartInfo.Arguments = args;
+	        process.StartInfo.UseShellExecute = false;
+		process.StartInfo.RedirectStandardInput = true;
+		process.StartInfo.RedirectStandardOutput = true;
+	
+        	_ = process.Start();
+
+	        writer = process.StandardInput;
+		reader = process.StandardOutput;
+		
+		System.Console.WriteLine ("gnu go has been started\n");
+		Init();	
+	}
+
+	/// Zakoncz działanie.
+	///
+	/// Funkcja zamyka stream'y do pisania i czytania,
+	/// a takşe kończy proces dzialania programu.
+	public OnExit() : void
+	{
+		writer.Close();
+		reader.Close();
+         	process.WaitForExit();
+		process.Close();
+	}
+ }
+}

Added: nemerle/trunk/snippets/gon/Goban.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/gon/Goban.n	Thu Dec 29 16:18:38 2005
@@ -0,0 +1,329 @@
+using System;
+using System.Text;
+using Nemerle.Collections;
+
+namespace Gon {
+ 
+ public enum Color {
+ 	| Black 
+ 	| White 
+	| Empty
+ }
+ /// klasa goban - reprezentacja planszy do gry w go.
+///
+ /// metody tej klasy sprawdzajÄ
 dostÄ™pność ruchu i sprzÄ
tajÄ
 po nim.
+ public class Goban 
+ {
+ 	/// prywatna klasa stone - reprezentacja pojedynczego kamienia.
+ 	private class Stone
+ 	{
+ 		public x: int;
+ 		public y: int;
+ 		public mutable group: Group;
+		
+ 		/// konstruktor klasy Stone.
+		///
+		/// cx, cy to wspolrzedne na planszy (gorny prawy rĂłg to 0,0), 
+		/// cgroup to grupa do której naleşy kamień.
+ 		public this(cx:int, cy:int, cgroup:Group)
+ 		{
+ 			x = cx;
+ 			y = cy;
+ 			group = cgroup;
+ 		}
+ 	}
+ 	/// prywanta klasa grupa - reprezentacja grupy polaczanych kamieni.
+	///
+	/// klasa posiada swoj rozmiar, ilosc oddechow i kolor
+ 	private class Group
+ 	{
+ 		public color : Color;
+ 		public mutable stones : list [Stone];
+ 		public mutable counter : int; /// breaths
+ 		public mutable size : int; /// number of stones;
+		
+		/// DoĹ‚Ä
cz grupÄ™.
+		///
+ 		/// Funkca ŁÄ
czy podanÄ
 grupÄ™ z grupÄ
 dla której Concat zostało wywołane.
+		/// Rozmiar grupy jest takĹźe zeminiany.
+ 		public Concat(g: Group): void
+ 		{
+ 			foreach (p in g.stones)
+ 				p.group = this;
+ 
+ 			stones += g.stones;
+			size += g.size;
+ 		}
+		
+ 		/// Dodaje kamień.
+		///
+		/// Funkcja Dodaje kamień do grupy i zmienia jej rozmiar.
+ 		public Add(n: Stone): void
+ 		{
+ 			stones = n::stones;
+			n.group = this;
+			size++;
+ 		}
+ 
+ 		/// StwĂłrz grupe.
+		///
+		/// Funkjca tworzy pustÄ
 grupe w podanym kolorze.
+		public this(col: Color)
+		{
+			color = col;
+			size = 0;
+			stones = [];
+		}
+ 	}
+ 
+	static directions : list [int * int]  = [(0,-1), (1,0), (0,1), (-1,0)];
+	/// prywatna klasa Breaths - reprezentacja listy oddechĂłw skojarzonej z kaĹźdym polem.
+	class Breaths 
+	{
+		public mutable places: array[2, list [Group]];
+		goban: Goban;
+		/// Wyczyść tablice oddechów i rozmiary grup.
+		///
+		/// Funkcja czuści tablice oddechów i ustawia rozmiary grup na 0.
+		public CleanUp() : void
+		{
+			mutable y = 0;
+			mutable x = 0;
+			for (; y < goban.size; y++)
+				for (x = 0; x < goban.size; x++)
+					places[x,y] = [];
+
+			foreach (p in goban.groups) p.counter = 0;
+			foreach (p in goban.groups) {
+				p.size = 0;
+				foreach (_ in p.stones) 
+					p.size++;
+			}
+		}
+		
+		/// Przelicz oddechy.
+		///
+		/// Funkcja tworzy listy grup skojrzonych z kaĹźdym polem na gobanie.
+		public Count(): void
+		{
+			mutable x = 0;
+			mutable y = 0;
+			def TryAdd(ox, oy) 
+			{
+				when (goban.area[x, y] == null && 
+					goban.Exists(ox, oy) && 
+					goban.area[ox, oy] != null) 
+				{
+					def group = goban.area[ox, oy].group;
+					when (places[x,y].Contains(group) == false) 
+					{
+						places[x, y] ::= group;
+						group.counter++;
+					}
+				}
+			}
+			CleanUp(); 
+			for (; y < goban.size; y++)
+				for (x = 0; x < goban.size; x++)
+					 foreach ((ox, oy) in directions) TryAdd(x + ox, y +oy);
+		}
+		
+		/// Konstruktor objektu Breaths.
+		///
+		/// Funkcja bierze goban dla którego stworzony objekt, ma liczyć oddechy.
+		public this(g: Goban)
+		{
+			goban = g;	
+ 			places = array(g.size, g.size);
+			CleanUp();	
+		}
+	}
+	/// rozmiar planszy.
+	public size: int;
+	/// para numer ruchu i pojedynczy zbity w nim kamień.
+	mutable ko: (int * Stone);
+	/// tablica kamieni.
+ 	mutable area: array[2, Stone];
+ 	mutable they: list [Group];
+	/// lista grup 
+ 	mutable groups: list [Group];
+	/// lista więzniów
+	mutable prisoners: list [Group];
+	/// lista ruchĂłw
+	mutable moves: list [(int*int*Color)];
+	/// numer ruchu
+	mutable move_number : int;
+	breaths: Breaths;
+	/// Parametr uzywany przez funkcje Is*
+ 	mutable x: int;
+	/// Parametr uzywany przez funkcje Is*
+ 	mutable y: int;
+	/// Parametr uzywany przez funkcje Is*
+ 	mutable color: Color;
+ 	
+ 	/// SprawdĹş czy samobĂłjstwo.
+	///
+	/// Funkcja sprawdza, czy badany ruchjest samobĂłjczy
+ 	IsSuicide(): bool
+ 	{
+		mutable ret = true;
+		
+		def CheckOne(g : Group) 
+		{
+			when ((g.color == color && g.counter > 1) || 
+				 (g.color != color && g.counter <= 1))
+				ret = false;
+		}
+		
+		def l = breaths.places[x, y];
+		when (l.IsEmpty)
+			ret = false;
+		foreach ((ox, oy) in directions)
+			when (Exists(x + ox, y + oy) && !NotEmpty(x+ox, y+oy))
+				ret = false;
+		when (ret)
+			foreach (g in l) 
+				CheckOne(g);
+		ret;
+ 	}
+	/// SprawdĹş czy ko
+	///
+	/// Funkcja sprawdza, czy w miejscu ruch nie występuje KO
+ 	IsKo(): bool
+ 	{
+                /// check if not IsKo
+		///
+                /// - remember from what pos was the last 1-elem. group beaten (if in previous turn)
+                /// - if this (remembered) pos is beaten then ko occurs
+
+ 		false;
+ 	}
+	
+	/// Zabij podanÄ
 grupÄ™.
+	///
+	/// Funkcja zabija i sciÄ
ga podanÄ
 grupe z planszy.
+	/// Martwe piony sÄ
 dodawane do listy prisoners, ustawiane jest ko.
+	Kill(g: Group): void
+	{
+		foreach (s in g.stones) 
+			area[s.x, s.y] = null;
+		/// (14:15:malekith) groups = groups.Filter (fun (y) { ! y.Equals (g) });
+		/// (14:24:kamil-skalski) public Remove (x : 'a) : list['a]  
+		groups = groups.Remove(g);
+		prisoners ::= g;
+		when (g.size == 1) 
+			ko = (move_number, g.stones.Head);
+	}
+	/// Sprawdz czy x,y istnieje.
+	///
+	/// Funkcja sprawdza, czy podany cx, cy nalezy do zakresy wielkości gobana.
+ 	public Exists(cx : int, cy: int): bool
+	{ 
+		(cx >= 0 && cy >= 0 && cx < size && cy < size); 
+		
+
+	}
+	/// Sprawdz czy x,y jest pełne.
+	///
+	/// Funkcja sprawdza czy w miejscu cx, cy stoi kamień.
+ 	public NotEmpty(cx:int, cy:int) : bool
+ 	{
+ 		 (Exists(cx, cy) && area[cx,cy] != null);
+ 	}
+	/// Sprawdź czy ruch jest dostępny.
+	///
+	/// Funkcja sprawdza czy w miejscu cx, cy moşna postawić piona
+	/// w kolorze col.
+ 	public Avaible(cx:int, cy:int, col:Color) : bool
+ 	{
+ 		x = cx;
+ 		y = cy;
+ 		color = col;
+ 
+ 		(Exists(x,y) && !NotEmpty(x, y) && !IsSuicide() && !IsKo());
+ 	}
+	/// Postaw kamień.
+	///
+	/// Funkcja próbuje postawić kamień, jeśli pole jest dostępne.
+	/// Po postawieniu kamienia wykonywane sÄ
 niezbędne czynności
+	/// porzÄ
dkujÄ
ce plansze.
+	public Put(cx: int, cy: int, col: Color) : void
+	{
+		mutable g = Group(col);
+		def s = Stone(cx, cy, g);
+		g.Add(s);
+		breaths.Count();
+		
+		def CheckOne(he) {
+			if (he.group.color == col) {
+				he.group.Concat(g);
+				groups = groups.Remove(g);
+				g = he.group;
+			} else {
+				when (they.Contains(he.group) == false) 
+					he.group.counter--;
+				when (he.group.counter == 0)
+					Kill(he.group);
+				they ::= he.group;
+			}
+		}
+		
+		def Neighbour(ox, oy)  {
+			when (NotEmpty(cx + ox, cy + oy)) 
+				CheckOne(area[cx + ox, cy + oy]);
+		}
+		
+		when (Avaible(cx, cy, col)) {
+		 	they = [];
+			foreach ((ox, oy) in directions) Neighbour(ox, oy);
+			area[cx, cy] = s;
+			when (groups.Contains(g) == false)
+				groups ::= g;
+
+			breaths.Count();
+			moves ::= (cx, cy, col);
+			move_number++;		
+			foreach ((ox, oy) in directions) 
+				when (NotEmpty(cx + ox, cy + oy)) {
+					def he = area[cx + ox, cy + oy];
+					when (he.group.color != col && he.group.counter <= 0) {
+						Kill(he.group);
+						Nemerle.IO.printf("killed %d\n", move_number);
+						breaths.Count();
+					}
+				}
+						
+		}
+	}
+	/// Zwróć tablice do narysowania.
+	///
+	/// Funkcja zwraca tablice rozmiar*rozmiar typu kolor
+ 	public State(): array[2, Color]
+	{
+ 		mutable ret = array(size, size);
+		for (y = 0; y < size; y++) 
+			for (x = 0; x < size; x++) {
+				ret[x,y] = Color.Empty;
+				when (NotEmpty(x,y)) 
+					ret[x,y] = area[x,y].group.color;
+			}
+		ret;
+	}
+	
+	/// konstruktor klasy Goban.
+	///
+	/// Funkcja bierze rozmiar planszy.
+ 	public this(s:int)
+ 	{
+ 		size = s;
+ 		area = array(s,s);
+		groups = [];
+		prisoners = [];
+		moves = [];
+		move_number = 0;
+		ko = (0, null);
+		breaths = Breaths(this);
+ 	}
+ 	
+ }
+} 

Added: nemerle/trunk/snippets/gon/GtkGame.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/gon/GtkGame.n	Thu Dec 29 16:18:38 2005
@@ -0,0 +1,327 @@
+using System;
+using Gtk;
+using Gon;
+namespace Gon {
+
+ /// Publiczna klasa GtkGame.
+ ///
+ /// Interfejs Input Output oparty o biblotekÄ™ gtk-sharp.
+ public class GtkGame: Game
+ {
+ 	/// Matryca rysujÄ
ca planszÄ™.
+	///
+	/// Glównym zadaniem tej klasy jest łapanie zdarzeń (events)
+	/// myszki i rysowanie planszy (goban).
+ 	class GobanBox : Gtk.DrawingArea
+	{
+		public game: GtkGame;
+		/// obraz białego kamienia.
+ 		white: Gdk.Pixbuf;
+		/// obraz czarnego kamienia.
+	 	black: Gdk.Pixbuf;
+		/// obraz białego właśnie postawionego kamienia.
+ 		swhite: Gdk.Pixbuf;
+		/// obraz czarnego właśnie postawionego kamienia.
+	 	sblack: Gdk.Pixbuf;
+		/// obraz tła matrycy.
+ 		ibg: Gdk.Pixbuf;
+		/// obraz podkładu planszy (wyświetlany nad tłem).
+ 		//igoban: Gdk.Pixbuf;
+	 	gc: Gdk.GC;
+ 		hor: Gdk.Pixbuf;
+	 	ver: Gdk.Pixbuf;
+ 	
+	 	startx: int;
+ 		starty: int;
+	 	bgsize: int;
+ 		stonesize: int;
+ 
+	 	goban_startx : int;
+ 		goban_starty: int;
+		/// po naciśnięciu przycisku myszy move zostaje
+		/// ustwiony na odpowiednie współrzędne.
+		public mutable move: int*int*Color;
+		/// przy zdarzeniu move_over, check zostaje
+		/// ustwiony na odpowiednie współrzędne.
+		public mutable check: int*int*Color;
+ 		/// Konstruktor klasy GobanBox.
+		///
+		/// Funkcja bierze objekt typu gra i ścieşke do katalogu
+		/// z grafikÄ
. Katalog z grafikÄ
 musi zwierać wszystkie wyszczególnione
+		/// plik dla grafiki: white.png , black.png , swhite.png , sblack.png , 
+		/// bg.png , goban.png , horizontal.png , vertical.png.
+	 	public this(game: GtkGame, path = "gfx/")
+ 		{
+	 		base();
+			
+ 			this.game = game;
+ 		
+ 			white = Gdk.Pixbuf(path + "white.png");
+ 			black = Gdk.Pixbuf(path + "black.png");
+	 		swhite = Gdk.Pixbuf(path + "swhite.png");
+ 			sblack = Gdk.Pixbuf(path + "sblack.png");
+	 		ibg = Gdk.Pixbuf(path + "bg2.jpg");
+	 		//igoban = Gdk.Pixbuf(path + "bg2.jpg");
+ 			ver = Gdk.Pixbuf(path + "horizontal.png");
+	 		hor = Gdk.Pixbuf(path + "vertical.png");
+ 		
+	 		gc = null; ///Gdk.GC(area.Pixmap);
+			
+ 			startx = 15;
+			starty = 15;
+	
+			bgsize = 300;
+			stonesize = 30;
+			move = (-1,-1, Color.Empty);
+			check = (-1, -1, Color.Empty);
+			def gsize = game.goban.size;
+	
+			goban_startx = startx + (2*bgsize  - stonesize*(gsize-1)) / 2;
+			goban_starty = starty + (2*bgsize - stonesize*(gsize-1)) / 2;
+			
+			ExposeEvent += fun (_) {
+	                        Draw (game.goban.State());
+	                }
+	
+			Events |= Gdk.EventMask.PointerMotionMask;
+			MotionNotifyEvent += fun (_, args:MotionNotifyEventArgs) {
+				def cx = ((args.Event.X :> int) - goban_startx + stonesize/2)/(stonesize);
+				def cy = ((args.Event.Y :> int) - goban_starty + stonesize/2)/(stonesize);
+				check = (cx, cy, game.current);
+			}
+			
+			Events |= Gdk.EventMask.ButtonPressMask;
+			ButtonPressEvent += fun (_, args:ButtonPressEventArgs) {
+				def cx = ((args.Event.X :> int) - goban_startx + stonesize/2)/(stonesize);
+				def cy = ((args.Event.Y :> int) - goban_starty + stonesize/2)/(stonesize);
+				move = (cx, cy, game.current);
+			}
+		}
+		/// Narysuj goban.
+		///
+		/// Funkcja rysuje goban, dostaje jako parametr tablicÄ™,
+		/// która powinna być stworzona przez funkcję goban->State();
+		public Draw(ret: array [2, Color]):void
+		{
+			mutable y = starty;
+			mutable x = startx;
+			def w = bgsize;
+			def h = bgsize;
+			def of = stonesize;
+			def gsize = game.goban.size;
+			mutable img = swhite;
+			
+			def DrawBg() {
+				GdkWindow.DrawPixbuf(gc, ibg, 0,0, x, y, w, h, 0, 0, 0);
+				x += w;
+				GdkWindow.DrawPixbuf(gc, ibg, 0,0, x, y, w, h, 0, 0, 0);
+				y += h;
+				x = startx;
+				GdkWindow.DrawPixbuf(gc, ibg, 0,0, x, y, w, h, 0, 0, 0);
+				x += w;
+				GdkWindow.DrawPixbuf(gc, ibg, 0,0, x, y, w, h, 0, 0, 0);
+			}
+			
+			def DrawLines() {
+				def len = 0;
+				for (mutable i = 0; i < gsize; i++) {
+					if (i == 0 || i == gsize-1) {
+						GdkWindow.DrawPixbuf (gc, ver, 0, 0, 
+							goban_startx, goban_starty + i * of, 
+							of * (gsize-1), 2,
+							0, 0, 0);
+											
+						GdkWindow.DrawPixbuf(gc, hor, 0,0, 
+							goban_startx + i*of,  goban_startx, 
+							2, of*(gsize-1), 
+							0, 0, 0);
+					} else {
+						GdkWindow.DrawPixbuf (gc, ver, 0, 0, 
+							goban_startx-len, goban_starty + i * of, 
+							of * (gsize-1) + len*2, 1,
+							0, 0, 0);
+											
+						GdkWindow.DrawPixbuf(gc, hor, 0,0, 
+							goban_startx + i*of,  goban_startx-len, 
+							1, of*(gsize-1) + len*2, 
+							0, 0, 0);
+					}
+				}
+			}
+			
+			def DrawLastStone (m: (int*int*Gon.Color)) {	
+				x = m[0];
+				y = m[1];
+				img = swhite;
+				when (m[2] == Color.Black)
+					img = sblack;
+				when (game.goban.Exists(x, y) || 
+					(m.Equals(move) && game.goban.NotEmpty(x,y)))
+					GdkWindow.DrawPixbuf(gc, img, 0,0, 
+					goban_startx + x*of + stonesize/2 - of, 
+					goban_starty + y*of + stonesize/2 - of,
+					stonesize, stonesize, 0, 0, 0);
+			}
+				
+			def DrawStones () {
+				for (y = 0; y < gsize; y++) {
+					for (x = 0; x < gsize; x++) {
+						when (ret[x,y] != Color.Empty) {
+							if (ret[x,y] == Color.Black)
+								img = black;
+							else
+								img = white;
+							GdkWindow.DrawPixbuf(gc, img, 0,0, 
+							goban_startx + x*of + stonesize/2 - of, 
+							goban_starty + y*of + stonesize/2 - of,
+							stonesize, stonesize, 0, 0, 0);
+						}
+						
+					}
+				}
+			}
+			
+			DrawBg();
+			DrawLines();
+			DrawStones();
+			DrawLastStone(move);
+//			DrawLastStone(check);
+			Show();
+		}
+	}
+	
+ 	class Panel : VBox
+	{
+ 		pas: Button;
+	 	quit: Button;
+		gobanbox : GobanBox;
+ 		public this(g: GobanBox)
+	 	{
+ 			base(false, 0);
+			gobanbox = g;
+ 			BorderWidth = 2;
+ 		
+	  	 	pas = Button("Pas");
+ 			quit = Button("Bye");
+ 			PackStart(pas, false, false, 3);
+	 		PackStart(quit, false, true, 2);
+			
+			pas.Clicked += fun (_) {
+				System.Console.WriteLine ("Pas");
+				gobanbox.move = (-2,-2, gobanbox.game.current);
+			}
+			
+			quit.Clicked += fun (_) { 
+				System.Console.WriteLine ("See ya");
+                		Application.Quit ();
+			}
+ 			pas.Show();
+ 			quit.Show();
+ 			Show();
+	 	}
+	}
+	 
+ 	class Displayer: Window 
+	{
+ 		box : HBox;
+		public gobanbox: GobanBox;
+	 	panel : Panel;
+		game: GtkGame;
+ 	
+ 		public this(game: GtkGame, bg: string)
+	 	{
+ 			base ("gon - nemerle go.");
+			this.game = game;
+ 			SetSizeRequest (640,640);
+ 		
+	 		box = HBox(false, 0);
+ 			gobanbox = GobanBox(game, bg);
+ 			panel = Panel(gobanbox);
+	 		box.PackStart (gobanbox, true, true, 0u);
+ 			box.PackStart (panel, false, false, 0u);
+ 		
+	 		gobanbox.Show();
+ 			panel.Show();
+	 		Show();
+ 
+ 			Add(box);
+			_  = Timeout.Add (100, game.Loop);
+	 	}
+
+        	protected override OnShown () : void
+	        {
+        	         base.OnShown();
+	        }
+	}
+	
+	displayer: Displayer;
+	mutable lm: int*int*Color;
+	showlast : bool;
+	/// Główna pętla dla interfejsu gtk.
+	///
+	/// Funkcja jest wywoływana co 100 ms,
+	/// pobiera ruchy od graczy i rysuje planszę - jeśli ruch został wykonany.
+	public Loop(): bool
+	{
+		
+		mutable m = (0,0,Color.Empty);
+		match (current) {
+		| Black => m = black.Get();
+		| White => m = white.Get();
+		| _ => ();
+		}
+		when (m.Equals((0,0,Color.Empty)))
+			m = displayer.gobanbox.move;
+		when (m.Equals((-2,-2,current))) {
+			if (current == Color.Black) {
+				white.SetMove(m[0], m[1]);
+				current = Color.White;
+			} else {	
+				black.SetMove(m[0], m[1]);
+				current = Color.Black;
+			}
+		
+		}
+		if (m.Equals((0,0,Color.Empty)) == false && goban.Avaible(m)) { 
+			goban.Put(m);
+			displayer.gobanbox.Draw(goban.State());
+			displayer.gobanbox.move = m;
+			if (current == Color.Black) {
+				white.SetMove(m[0], m[1]);
+				current = Color.White;
+			} else {	
+				black.SetMove(m[0], m[1]);
+				current = Color.Black;
+			}
+		} else {
+			m = displayer.gobanbox.check;
+			when (showlast && m.Equals(lm) == false && goban.Avaible(m)) {
+				displayer.gobanbox.Draw(goban.State());
+				lm = m;
+			}
+		}
+		true;
+	}
+
+	/// Konstruktor GtkGame.
+	///
+	/// Funkcja bierze rozmiar, dwa objekty typu Player i ścieşkę do katalogu
+	/// z grafikÄ
 dla GobanBox.
+	public this (size: int, b: Player, w:Player, bg:string)
+	{
+		base(Goban(size), b, w);
+ 		Application.Init();
+		displayer = Displayer(this, bg);
+                displayer.DeleteEvent += fun (_) { Application.Quit () };
+                displayer.ShowAll ();
+ 		Application.Run();
+		lm = (-1, -1, Color.Empty);
+		showlast = false;
+	}
+ }
+ 
+ public class GtkPlayer: Player
+ {
+ 	public this(n:string, clr: Color) { base(n, clr) }
+ }
+}

Added: nemerle/trunk/snippets/gon/Main.n
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/gon/Main.n	Thu Dec 29 16:18:38 2005
@@ -0,0 +1,20 @@
+using Gon;
+
+module Go {
+  	public static Main (args : array [string]) : void
+	{
+		System.Console.WriteLine ("gon v 0.1");
+		mutable size = 13;
+		mutable bg = "gfx/";
+		when (args.Length >= 1) {
+			size = System.Int32.Parse(args[0]);
+			when (size > 21 || size < 5)
+				size = 13;
+		}
+
+		when (args.Length >= 2) 
+			bg = args[1];
+	 	_ = GtkGame(size, GtkPlayer("foo", Color.Black), GnuGoPlayer(size, Color.White), bg);
+ 	}
+}
+

Added: nemerle/trunk/snippets/gon/Makefile
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/gon/Makefile	Thu Dec 29 16:18:38 2005
@@ -0,0 +1,15 @@
+NAME    = gon
+SRC     = Game.n Goban.n GtkGame.n Main.n GnuGoPlayer.n
+MONO    = mono
+COMPILE = ncc
+
+all: $(SRC)
+	$(COMPILE) -pkg gtk-sharp -texe -out:$(NAME).exe $(SRC)
+
+doc: $(SRC)
+	$(COMPILE) -pkg gtk-sharp -texe -out:$(NAME).exe $(SRC) -doc:doc/gon.xml
+run: all
+	$(MONO) $(NAME).exe mono 9 
+
+clean:
+	rm -f $(NAME).exe

Added: nemerle/trunk/snippets/gon/doc-pl/class.txt
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/gon/doc-pl/class.txt	Thu Dec 29 16:18:38 2005
@@ -0,0 +1,12 @@
+ public abstract class Player - klasa stanowiąca szkielet gracza.
+ public abstract class Game  - klas stanowiąca szkielet gry.
+ public class GnuGoPlayer: Player - gracz, pod którym kryje się program gnugo.
+ public class Goban - klasa reprezentująca plansze i wszystko co się na niej dzieje.
+	Stone - klasa reprezentująca kamień.
+ 	Group - klasa reprezentująca grupe kamieni i akcje na grupach.
+	Breaths - klasa reprezentująca listę oddechów na planszy.
+ public class GtkGame: Game - rozszerzona gra, o interfejs gtk-sharp.
+ 	class GobanBox : Gtk.DrawingArea - klasa która reprezentuje wyświetlacz planszy.
+ 	class Panel : VBox - klasa która repreznetuje panel kontrolny gry - przyciski, wyniki itp.
+ 	class Displayer: Window - klasa, która zawiera wyświetlacz planszy i panel kontrolny.
+ public class GtkPlayer: Player - rozszerzony gracz dla gtk-sharp.

Added: nemerle/trunk/snippets/gon/doc-pl/reusing.txt
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/gon/doc-pl/reusing.txt	Thu Dec 29 16:18:38 2005
@@ -0,0 +1,7 @@
+zarowno klase Player jak i klase Game (znajduja się w Game.n)
+mozna latwo wykorzystac jako klasy bazowe dla wszelkich gier planszowych,
+takich jak szachy czy warcaby.
+Są to abstrakcyjne modele gry i gracza. Klasa gracz ma 2 wirtualne metody
+Get i SetMove, ktore w zaleznosci od tego co dana klasa dziedziczaca ma
+robic moga byc odpowiednio zastapione. Get moze brac np klawisze z 
+klawiatury albo z zewnetrznego programu grajacego w szachy (gnuchees)

Added: nemerle/trunk/snippets/gon/doc-pl/systemControl.txt
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/gon/doc-pl/systemControl.txt	Thu Dec 29 16:18:38 2005
@@ -0,0 +1,44 @@
+opis programu ngo:
+program używa dwóch odrębnych części planszy i interfejsu,
+
+1 pierwsza czescia jest plansza i wszystko co z nia zwiazane.
+  1.1 okreslanie dopuszczalnosci ruchu:
+      -sprawdzanie czy mozna postawic piona (puste, istnieje).
+      -sprawdzanie czy nie jest to samobojstwo
+      -sprawdzanie czy nie jest to ko
+   
+  1.2 robienie porzadku na planszy:
+      -dokladanie piona lub stworzenie nowej grupy
+      -przeliczenie oddechow grup zwiazanych z pionem
+      -usuwanie martwych grup
+
+  1.3 obliczenie stanu koncowego gry.
+
+
+2 drugą częścią jest interfejs użytkownika, złożony z wejścia i wyjścia.
+  2.1 wejście :
+      -pobranie adresu ruchu, informacji pas, lub komunikatu.
+   
+  2.2 wyjscie :
+      -narysowanie bierzacego stanu planszy.
+
+szkic działania programu
+program działa do czasu otrzymania z wejścia komunikatu o zakonczeniu.
+1 jeśli obydwaj userzy spasują 
+	lub nie istnieje miejsce w które można położyć kamień,
+	przejdź do 2
+1.1 pobierz od gracza miejsce ruch, 
+	jesli czas ruch sie wyczerpal przejdz do 1.5
+	jesli otrzymales pas przejdz do 1.4
+	jesli otrzymales koniec przejdz do 3.
+1.2 sprawdz czy miejsce ruchu jest prawidlowe, jesli nie wroc do 1.1,
+1.3 zrob porzadek na planszy.
+1.4 narysuj plansze.
+1.5 zmien gracza przejdz do 1
+
+2 policz punkty i wyswietl wyniki
+
+3 zakoncz program
+
+
+

Added: nemerle/trunk/snippets/gon/doc-pl/uml.dia
==============================================================================
Binary file. No diff available.

Added: nemerle/trunk/snippets/gon/gfx/bg2.jpg
==============================================================================
Binary file. No diff available.

Added: nemerle/trunk/snippets/gon/gfx/black.png
==============================================================================
Binary file. No diff available.

Added: nemerle/trunk/snippets/gon/gfx/horizontal.png
==============================================================================
Binary file. No diff available.

Added: nemerle/trunk/snippets/gon/gfx/sblack.png
==============================================================================
Binary file. No diff available.

Added: nemerle/trunk/snippets/gon/gfx/swhite.png
==============================================================================
Binary file. No diff available.

Added: nemerle/trunk/snippets/gon/gfx/vertical.png
==============================================================================
Binary file. No diff available.

Added: nemerle/trunk/snippets/gon/gfx/white.png
==============================================================================
Binary file. No diff available.



More information about the svn mailing list