OliThink GUI in Java... Complete source posted

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

OliverBr
Posts: 725
Joined: Tue Dec 18, 2007 9:38 pm
Location: Munich, Germany
Full name: Dr. Oliver Brausch

OliThink GUI in Java... Complete source posted

Post by OliverBr »

It's really amazing how easy and short you can do graphical stuff in Java, so I will post the sources here.


Interface Methods from Engine:

Here the engine should send the current board in FEN-Notation:

Code: Select all

public synchronized static void parsePos(String pos);


Here the engine should send its move. It's only for animating the move and not absolutely necessary:

Code: Select all

public synchronized static void engineMove(int fromcol, int fromrow, int tocol, int torow);


Interface Method to Engine:
Here the engine should send its move. It's only for animating the move and not absolutely necessary:

Code: Select all

OliThink.receiveCommand(String cmd);
And here the sources:

Code: Select all

OliThinkApplet.java:

import java.awt.Component;
import java.awt.Container;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JApplet;

/**
 * @author Oliver Brausch 25.11.2009
 */
public class OliThinkApplet extends JApplet implements MouseListener, MouseMotionListener {
	private static final long serialVersionUID = 1L;
	static int ix = 0;
	static int iy = 0;
	static Piece thisPiece = null;
	static Container cpane;
	static OliThinkApplet applet;
	
	public void init() {
		applet = this;
		cpane = getContentPane();
		cpane.setLayout(null);
		
		TimerTask engine = new TimerTask() {
			public void run() {
				OliThink.main(new String[]{});
			}
		};
		new Timer().schedule(engine, 0L);
		OliThink.receiveCommand("time 3000");
	}
	
	public void stop() {
		OliThink.receiveCommand("quit");
	}

	public synchronized static void parsePos(String pos) {
		cpane.removeAll();
		thisPiece = null;
		
		int col = 7, row = 0;
		for (int i = pos.length() - 1; i >= 0; i--) {
			char s = pos.charAt(i);
			if (s == '/') {
				row++;
				col = 7;
			&#125; else if &#40;s >= '1' && s <= '8') &#123;
				col -= s - '0';
			&#125; else &#123;
				applet.activatePiece&#40;new Piece&#40;s, col--, row&#41;);
			&#125;
		&#125;
		for &#40;col = 0; col < 8; col ++) 
			for &#40;row = 0; row < 8; row ++) 
				cpane.add&#40;new Square&#40;col, row&#41;);
		applet.repaint&#40;);
	&#125;
	

	public synchronized static void engineMove&#40;int fromcol, int fromrow, int tocol, int torow&#41; &#123;
		int fromx = fromcol*70;
		int fromy = &#40;7-fromrow&#41;*70;
		int tox = tocol*70;
		int toy = &#40;7-torow&#41;*70;

		Piece p = findPiece&#40;fromcol, fromrow&#41;;
		for &#40;int i = 1; i < 100; i++) try &#123;
			int x = fromx + i*&#40;tox-fromx&#41;/100;
			int y = fromy + i*&#40;toy-fromy&#41;/100;
			p.setBounds&#40;x, y&#41;;
			Thread.sleep&#40;1L&#41;;
		&#125; catch &#40;InterruptedException ie&#41; &#123;
		&#125;
		p.setBounds&#40;tox, toy&#41;;
	&#125;
	
	private synchronized static Piece findPiece&#40;int col, int row&#41; &#123;
		Component&#91;&#93; comps = cpane.getComponents&#40;);
		for &#40;Component comp &#58; comps&#41; &#123;
			if &#40;comp instanceof Piece && (&#40;Piece&#41;comp&#41;.isThere&#40;col, row&#41;) 
				return &#40;Piece&#41;comp;
		&#125;
		return null;
	&#125;
		
	private synchronized void activatePiece&#40;Piece p&#41; &#123;
		p.addMouseListener&#40;this&#41;;
		p.addMouseMotionListener&#40;this&#41;;
		cpane.add&#40;p&#41;;		
		p.setOpaque&#40;false&#41;;
	&#125;
	
	public void mouseClicked&#40;MouseEvent arg0&#41; &#123;
	&#125;

	public void mouseEntered&#40;MouseEvent arg0&#41; &#123;
	&#125;

	public void mouseExited&#40;MouseEvent arg0&#41; &#123;
	&#125;

	public void mousePressed&#40;MouseEvent arg0&#41; &#123;
		thisPiece = &#40;Piece&#41; arg0.getSource&#40;);
		ix = thisPiece.getX&#40;);
		iy = thisPiece.getY&#40;);
	&#125;

	public void mouseReleased&#40;MouseEvent arg0&#41; &#123;
		if &#40;thisPiece == null&#41; thisPiece = &#40;Piece&#41; arg0.getSource&#40;);
		int col = thisPiece.col;
		int row = thisPiece.row;
		int type = thisPiece.type;
		thisPiece = null;
		int newcol = &#40;ix+34&#41;/70;
		int newrow = 7-&#40;iy+34&#41;/70;

		if &#40;newcol != col || newrow != row&#41; &#123;
			String move = String.valueOf&#40;&#40;char&#41;('a' + col&#41;) + &#40;char&#41;('1' + row&#41; 
					+ &#40;char&#41;('a' + newcol&#41; + &#40;char&#41;('1' + newrow&#41;;
			
			if (&#40;type == 'p' || type == 'P') && &#40;newrow == 7 || newrow == 0&#41;) move += "q";
			OliThink.receiveCommand&#40;move&#41;;
		&#125;
	&#125;
	
	public void mouseDragged&#40;MouseEvent arg0&#41; &#123;
		if &#40;thisPiece == null&#41; thisPiece = &#40;Piece&#41; arg0.getSource&#40;);
		arg0.translatePoint&#40;ix, iy&#41;;
		ix = arg0.getX&#40;) - 35;
		iy = arg0.getY&#40;) - 35;
		thisPiece.setBounds&#40;ix, iy&#41;;
		this.repaint&#40;);
	&#125;

	public void mouseMoved&#40;MouseEvent arg0&#41; &#123;
	&#125;
&#125;
And other two small classes in object-orientated manner:

Code: Select all

Square.java&#58;

import java.awt.Color;
import javax.swing.JPanel;

/**
 * @author Oliver Brausch 25.11.2009
 */
public class Square extends JPanel &#123;
	private static final long serialVersionUID = 1L;
					
	public Square&#40;int col, int row&#41; &#123;
		super.setBounds&#40;col*70, &#40;7-row&#41;*70, 70, 70&#41;;
		super.setBackground&#40;&#40;col + row&#41; % 2 == 1 ? new Color&#40;216, 216, 216&#41; &#58; new Color&#40;64, 64, 64&#41;);
	&#125;	
&#125;

Code: Select all

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

/**
 * @author Oliver Brausch 25.11.2009
 */
public class Piece extends JPanel &#123;
	private static final long serialVersionUID = 1L;
	private BufferedImage img = null;
	char type;
	int col;
	int row;

	public Piece&#40;char type, int col, int row&#41; &#123;
		this.type = type;
		this.col = col;
		this.row = row;
		this.setBounds&#40;col*70, &#40;7-row&#41;*70&#41;;
		
		String color = Character.isUpperCase&#40;type&#41; ? "W" &#58; "b";
		String image = "res/" + color + String.valueOf&#40;type&#41; + ".png";
		
		try &#123;
			InputStream is = getClass&#40;).getResourceAsStream&#40;image&#41;;
			this.img = ImageIO.read&#40;is&#41;;
		&#125; catch &#40;Exception io&#41; &#123;
			io.printStackTrace&#40;);
		&#125;
	&#125;
	
	public boolean isThere&#40;int testcol, int testrow&#41; &#123;
		return testcol == col && testrow == row;
	&#125;
	
	public void setBounds&#40;int x, int y&#41; &#123;
		super.setBounds&#40;x, y, 70, 70&#41;;
	&#125;
	
	public void paintComponent&#40;Graphics g&#41; &#123;
		if &#40;this.img != null&#41; g.drawImage&#40;this.img, 0, 0, this&#41;;
	&#125;	
&#125;

Gerd Isenberg
Posts: 2250
Joined: Wed Mar 08, 2006 8:47 pm
Location: Hattingen, Germany

Re: OliThink GUI in Java... Complete source posted

Post by Gerd Isenberg »

Nice and clean!
pkappler
Posts: 38
Joined: Thu Mar 09, 2006 2:19 am

Re: OliThink GUI in Java... Complete source posted

Post by pkappler »

Hi Oliver,

Thanks for posting this!

I was just browsing your website and noticed that you ported your engine from C to Java. I'm curious - how much slower is the Java version?

-Peter
OliverBr
Posts: 725
Joined: Tue Dec 18, 2007 9:38 pm
Location: Munich, Germany
Full name: Dr. Oliver Brausch

Re: OliThink GUI in Java... Complete source posted

Post by OliverBr »

It's about half as fast as the native C code on a 32 bit JavaVM.

I got similar results with OliThink4.

For me this result was suprisingly good. Java is not so slow as many think and as you see with my graphical interface, it's much more powerful in features.