You are on page 1of 25

Vamos a empezar la serie mediante la aplicacin de un poco de juego de ajedrez.

La idea es
mostrar todas las piezas y dejar al usuario arrastrar las piezas en torno al uso de su ratn. En
prximos artculos vamos a seguir para extender este ejemplo bsico mediante la introduccin
de ms y ms complejas funcionalidades. Sin embargo, el primer artculo se centrar en las
funcionalidades Gui muy bsicas. El lenguaje de programacin para esta serie es Java.

Objetivo: Proporcionar una interfaz de usuario para arrastrar las imgenes de las
piezas del juego alrededor.
Comenzamos con la introduccin de una serie de convenciones que hacen que sea ms fcil de
entender los siguientes fragmentos de cdigo fuente. La primera es que cada vez que utilizamos
un objeto List, consideramos que el elemento en el ndice 0 para ser el tema de fondo ,
mientras que el elemento en el ndice list.size () -1 ser el primer elemento. Los segundos
convenciones, es para todas las coordenadas x e y marcarn la esquina superior
izquierda del elemento para mostrar. Y por ltimo pero no menos importante que utilizamos el
sistema de coordinacin estndar proporcionada por Java, lo que significa que lacoordenada
0/0 ser la esquina superior izquierda de la pantalla / marco / panel de / etc.
Ok, as que vamos a empezar. Crearemos tres clases. Una clase (ChessGui) ser la principal
clase de interfaz de usuario que es responsable de mostrar el marco de aplicaciones y el dibujo
de fondo y piezas. La segunda clase (piezas) representa una pieza del juego con sus
caractersticas. La tercera clase (PiecesDragAndDropListener) es responsable del manejo de
eventos de ratn y por lo tanto el manejo de arrastrar y soltar las piezas del juego.
Primero creamos nuestra clase principal GUI llamada ChessGui. Extendemos desde JPanel y lo
utilizaremos para dibujar las piezas del juego y crear el marco de aplicaciones.
1
2
3
pblico de clase ChessGui extiende JPanel {
/ / ..
}
Lo que queremos mostrar es una imagen de fondo que contiene el tablero de ajedrez y las
piezas que el usuario ser capaz de arrastrar. Como tenemos que realizar un seguimiento de
todas las piezas del juego, vamos a guardarlas en una lista. Las constantes BOARD_START_X,
BOARD_START_Y, TILE_OFFSET_X y TILE_OFFSET_Y nos ayudarn a ajustar la posicin de las
piezas en la pantalla.

BOARD_START_X y BOARD_START_Y

TILE_OFFSET_X y TILE_OFFSET_Y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
pblico de clase ChessGui extiende JPanel {
/ / ..
pblica ChessGui () {
Image / / carga y conjunto de antecedentes
URL = urlBackgroundImg getClass () getResource (. "/ ch01/img/wood.jpg" );
este . imgBackground = nuevo . ImageIcon (urlBackgroundImg) getImage ();

/ / Crear y colocar las piezas
/ /
/ / Torre, caballo, alfil, reina, rey, obispo, caballero, y la torre
createAndAddPiece (Color_White, TYPE_ROOK, BOARD_START_X + TILE_OFFSET_X * 0 ,
BOARD_START_Y + TILE_OFFSET_Y * 7 );
createAndAddPiece (Color_White, TYPE_KNIGHT, BOARD_START_X + TILE_OFFSET_X * 1
,
BOARD_START_Y + TILE_OFFSET_Y * 7 );
createAndAddPiece (Color_White, TYPE_BISHOP, BOARD_START_X + TILE_OFFSET_X * 2
,
BOARD_START_Y + TILE_OFFSET_Y * 7 );
createAndAddPiece (Color_White, TYPE_KING, BOARD_START_X + TILE_OFFSET_X * 3 ,
BOARD_START_Y + TILE_OFFSET_Y * 7 );
createAndAddPiece (Color_White, TYPE_QUEEN, BOARD_START_X + TILE_OFFSET_X * 4
,
BOARD_START_Y + TILE_OFFSET_Y * 7 );
createAndAddPiece (Color_White, TYPE_BISHOP, BOARD_START_X + TILE_OFFSET_X * 5
,
BOARD_START_Y + TILE_OFFSET_Y * 7 );
createAndAddPiece (Color_White, TYPE_KNIGHT, BOARD_START_X + TILE_OFFSET_X * 6
,
BOARD_START_Y + TILE_OFFSET_Y * 7 );
createAndAddPiece (Color_White, TYPE_ROOK, BOARD_START_X + TILE_OFFSET_X * 7 ,
BOARD_START_Y + TILE_OFFSET_Y * 7 );
/ / peones
para ( int i = 0 ; i < 8 ; i + +) {
createAndAddPiece (Color_White, TYPE_PAWN, BOARD_START_X + TILE_OFFSET_X *
i,
BOARD_START_Y + TILE_OFFSET_Y * 6 );
}

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
createAndAddPiece (Color_Black, TYPE_ROOK, BOARD_START_X + TILE_OFFSET_X * 0 ,
BOARD_START_Y + TILE_OFFSET_Y * 0 );
createAndAddPiece (Color_Black, TYPE_KNIGHT, BOARD_START_X + TILE_OFFSET_X * 1
,
BOARD_START_Y + TILE_OFFSET_Y * 0 );
createAndAddPiece (Color_Black, TYPE_BISHOP, BOARD_START_X + TILE_OFFSET_X * 2
,
BOARD_START_Y + TILE_OFFSET_Y * 0 );
createAndAddPiece (Color_Black, TYPE_QUEEN, BOARD_START_X + TILE_OFFSET_X * 3
,
BOARD_START_Y + TILE_OFFSET_Y * 0 );
createAndAddPiece (Color_Black, TYPE_KING, BOARD_START_X + TILE_OFFSET_X * 4 ,
BOARD_START_Y + TILE_OFFSET_Y * 0 );
createAndAddPiece (Color_Black, TYPE_BISHOP, BOARD_START_X + TILE_OFFSET_X * 5
,
BOARD_START_Y + TILE_OFFSET_Y * 0 );
createAndAddPiece (Color_Black, TYPE_KNIGHT, BOARD_START_X + TILE_OFFSET_X * 6
,
BOARD_START_Y + TILE_OFFSET_Y * 0 );
createAndAddPiece (Color_Black, TYPE_ROOK, BOARD_START_X + TILE_OFFSET_X * 7 ,
BOARD_START_Y + TILE_OFFSET_Y * 0 );
para ( int i = 0 ; i < 8 ; i + +) {
createAndAddPiece (Color_Black, TYPE_PAWN, BOARD_START_X + TILE_OFFSET_X *
i,
BOARD_START_Y + TILE_OFFSET_Y * 1 );
}

/ / Aadir detectores de ratn para permitir arrastrar y soltar
/ /
PiecesDragAndDropListener oyente = nueva PiecesDragAndDropListener ( esto .
piezas,
este );
este . addMouseListener (oyente);
este . addMouseMotionListener (oyente);

/ / Crear el marco de aplicacin y establecer visible
/ /
JFrame f = nuevo JFrame ();
f.setVisible ( verdadero );
f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
f.add ( este );
f.setSize ( este imgBackground.getWidth (. nula ), este
imgBackground.getHeight (. nulo ));
}
/ / ..
}
La creacin de las piezas del juego se ha puesto en un mtodo adicional, ya que es el mismo
para todas las piezas. Una ventaja adicional es que se asla el cdigo y podemos cambiar el
mtodo fcilmente ms tarde si es necesario.
1
2
3
4
/ / ..

/ **
* Crear una pieza del juego
*
5
6
7
8
9
10
11
12
13
14
15
16
* @ Param color de color constante
* Platea @ param constante
* @ Param posicin xx de la esquina superior izquierda
* Posicin yy @ param de la esquina superior izquierda
* /
privado void createAndAddPiece ( int color, int tipo, int x, int y)
{
Image img = esta getImageForPiece (color, tipo).;
PEDAZO = nueva Piece (img, x, y);
este . pieces.add (pieza);
}
/ / ..
El cdigo para cargar las imgenes de las piezas del juego se ha puesto en un mtodo separado
tambin. Una de las razones es, que he jugado un poco con diferentes conjuntos de iconos para
las piezas y tener el cdigo para generar el nombre del archivo de imagen en un solo lugar lo
hizo mucho ms fcil cambiar de un convenio de denominacin a otra.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/ / ..

/ **
* Imagen de carga para el color y el tipo dado. Este mtodo se traduce el
color y
* Escribir informacin en un nombre de archivo y carga ese archivo en
particular.
*
* @ Param color de color constante
* Platea @ param constante
* @ Imagen de retorno
* /
privada de imagen getImageForPiece ( int color, int tipo) {

String filename = "" ;

nombre + = (color == Color_White? "w" : "b" );
interruptor (tipo) {
caso TYPE_BISHOP:
nombre + = "b" ;
romper ;
caso TYPE_KING:
nombre + = "k" ;
romper ;
caso TYPE_KNIGHT:
nombre + = "n" ;
romper ;
caso TYPE_PAWN:
nombre + = "p" ;
romper ;
caso TYPE_QUEEN:
nombre + = "q" ;
romper ;
caso TYPE_ROOK:
nombre + = "r" ;
romper ;
31
32
33
34
35
36
37
38
39
40
41
}
nombre + = ". png" ;

URL = urlPieceImg getClass () getResource (. "/ ch01/img /" + nombre de
archivo);
volver nueva ImageIcon (urlPieceImg) getImage ().;
}
/ / ..
El mtodo paintComponent () es simplemente dibujando la imagen de fondo y despus todas las
piezas en el orden de abajo hacia arriba. El pedido se realiza automticamente por nosotros, ya
que el iterador interno se repetir la lista en orden ascendente empezando por el elemento 0.
1
2
3
4
5
6
7
8
9
/ / ..
@ Override
protegida vaco paintComponent (Graphics g) {
g.drawImage ( este imgBackground,. 0 , 0 , NULL );
de (pieza por pieza: este . piezas) {
g.drawImage (piece.getImage (), piece.getX (), piece.getY
(), nulo );
}
}
/ / ..
La siguiente clase que creamos se llama "Piece". Representa una pieza del juego con sus
caractersticas: la imagen que representa la pieza de juego y la coordenadas x / y para la
visualizacin de la pieza de juego.
1
2
3
4
5
6
7
8
pblico de clase Pedazo {

privado img Imagen;
privada int x;
privada int y;

/ / ..
}
La ltima clase es PiecesDragAndDropListener. Est implementando las interfaces MouseListener
y MouseMotionListener y se encarga de detectar si el ratn est asomando sobre una pieza del
juego cuando el usuario inicia presionando el botn del ratn. Si este es el caso, el componente
ms superior en esa posicin se convierte en el dragPiece y se mueve a lo largo con el ratn
mientras el usuario mantiene presionado el botn del ratn.

dragOffsetX y dragOffsetY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
pblico de clase PiecesDragAndDropListener implementa MouseListener,
MouseMotionListener {

privadas pedazos Lista <Piece>;
privado chessGui ChessGui;

privado dragPiece pieza;
privada int dragOffsetX;
privada int dragOffsetY;

pblica PiecesDragAndDropListener (piezas Lista <Piece>, ChessGui chessGui) {
este . piezas = piezas;
este . chessGui = chessGui;
}

@ Override
pblico void mousePressed (evt MouseEvent) {
int x = evt.getPoint () x.;
int y = evt.getPoint () y.;

/ / Averiguar qu pieza se mueva.
/ / Comprobamos la lista de arriba a buttom
/ / (Por lo tanto itereate en orden inverso)
/ /
para ( int i = esta pieces.size () -. 1 ; i> = 0 ; i -) {
PEDAZO = esta pieces.get (i).;

si (mouseOverPiece (pieza, x, y)) {
/ / Calcular offset, porque no queremos que la pieza de arrastre
/ / Para saltar con su esquina superior izquierda a la actual del ratn
/ / Posicin
/ /
este dragOffsetX = x - piece.getX ().;
este . dragOffsetY = y - piece.getY ();
este . dragPiece = pieza;
romper ;
}
}
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

/ / Mover arrastrando pieza a la parte superior de la lista
si ( esto . dragPiece! = NULL ) {
este . pieces.remove ( este dragPiece.);
este . pieces.add ( este dragPiece.);
}
}

/ **
* Comprobar si el ratn est actualmente por encima de esta pieza
* @ Param pieza de la pieza de juego
* @ Param xx coordenadas de ratn
* Yy @ param coordenada del ratn
* @ Return true si el ratn est sobre la pieza
* /
privado boolean mouseOverPiece (pieza Piece, int x, int y) {
volver piece.getX () <= x
&& Piece.getX () + piece.getWidth ()> = x
&& Piece.getY () <= y
&& Piece.getY () + piece.getHeight ()> = y;
}

@ Override
pblico void mouseReleased (MouseEvent arg0) {
este dragPiece =. nula ;
}

@ Override
pblico void mouseDragged (evt MouseEvent) {
si ( esto . dragPiece! = NULL ) {
este . dragPiece.setX (evt.getPoint () x -. este dragOffsetX.);
este . dragPiece.setY (. evt.getPoint () y - esta dragOffsetY.);
este . chessGui.repaint ();
}

}

/ / ..
}
Mirando hacia atrs en el PiecesDragAndDropListener, tengo que decir, que podra haber
proporcionado slo la instancia chessGui en el constructor en lugar de la chessGui y la lista de
piezas, debido a que el chessGui incluye la lista de piezas. Si desea usted puede implementar
ese cambio como un ejercicio por su cuenta ;-)
. Aunque esta aplicacin parece muy, muy bsico, tiene un par de ventajas interesantes sobre
otros enfoques, como la aplicacin de las reglas de juego, etc Las principales ventajas son:
La aplicacin y de cdigo fuente es fcil de implementar y entender .
El enfoque es muy bueno para la creacin de prototipos de juegos, ya que no se requieren
cambios en las aplicaciones para probar nuevas reglas.
Jugar con reglas de la casa no es ningn problema, ya que las reglas de juego normales no se
aplican.
Configuracin de ejemplo de juego escenarios es fcil ya que las piezas se pueden arrastrar
libremente.
Sin embargo, tambin hay algunas desventajas:
El usuario puede hacer a sabiendas o no se mueve no vlidos .
Los usuarios tienen que conocer y acordar las reglas en la delantera.
Eso es todo por ahora. En el siguiente artculo vamos a introducir el concepto de estado del
juego .
Recursos:
El cdigo fuente (proyecto Eclipse): cdigo fuente (actualizado 27.11.2012)
Los iconos de ajedrez es de: http://ixian.com/chess/jin-piece-sets/

piece jin conjuntos

cmo utilizar
stos son juegos de piezas de tamaos nxn para todos en N:
20-48, 52, 56, 60, 64, 72, 80, 88, 96, 112, 128, 144 y 300 para
su uso con el Jin cliente grfico para los servidores de ajedrez. .
Para cualquier archivo zip suministrado; simplemente copiar el
archivo en el ejemplo INSTALL/jin-2.14.1/resources/pieces
/directorio; no hay necesidad de descomprimirlo. La prxima
vez que Jin se invoca, automticamente se pondr a disposicin
de los nuevos conjuntos de piezas. Para verlas, vaya al men
"Preferences / Tablero de ajedrez ...", entonces el "| Mira |"
ficha, y consultar las "Piezas | Set:". Casilla de informacin
sobre estos tipos de piezas se probaron bajo Jin 2.14.1
corriendo bajo la versin de Sun Java 1.6.0_07, a su vez, se
ejecuta bajo Linux Debian 4.0r4 (versin del kernel 2.6.26-1-
686). capturas licencia de este trabajo por Eric De Mund est
bajo una licencia de Creative Commons Attribution-Share Alike
3.0 Unported pgina principal de ajedrez





























Los comentarios son bienvenidos en el ajedrez DASH <ead AT
com> DOT Ixian. $ Ixian: index.htm, v 1.3 2009-03-22
00:21:36 ead Exp $ [ visitas desde el 2008-08-06]

En este artculo vamos a separar la lgica interna del juego de la lgica de la interfaz de
usuario. En el camino vamos a echar un vistazo a las ventajas y desventajas de este enfoque. El
lenguaje de programacin Java es de nuevo.

Esta es la tercera parte de una serie de artculos acerca de la programacin de un juego de
ajedrez en Java con Swing. Como todos los artculos se acumulan unos sobre otros, le animo a
que tambin echar un vistazo a los artculos anteriores de esta serie ( Chess01: Arrastrar las
piezas del juego , Chess02: Presentacin de estado del juego ).
Qu significa la "lgica interna del juego '? Bsicamente significa que tenemos todo lo que
conceptualmente pertenece al juego sin preocuparse acerca de cmo esto es eventualmente
presentada al usuario. En nuestro ejemplo de ajedrez, podemos pensar en el ajedrez como un
juego que consiste en un tablero, algunas piezas y las reglas. Esto es cierto para todos los
juegos de ajedrez. Ya sea que se presenta con las piezas del juego fsico en una tabla o en una
pantalla de ordenador usando arrastrar y soltar o mediante una interfaz de lnea de comandos
no hace ninguna diferencia. Todava Nos exigira el mismo tablero, las piezas y las reglas.
En nuestro caso, el tablero de juego no se presenta como tal. Sin embargo, existe
implcitamente en forma de localizaciones que se almacenan en cada pieza y las reglas que se
aplican.
Y por qu tenemos que separar la lgica de la interfaz de usuario de la lgica del juego?Bueno,
hay varias razones para ello:
Aplicacin de las reglas es mucho ms fcil de implementar, ya que podemos programar las
reglas usando una representacin apropiada del juego (por ejemplo, no nos tenemos que
preocupar por coordenadas X / Y).
Es mucho ms fcil cambiar la interfaz de usuario actual , ya que no hay que preocuparse
por romper el juego subyacente.
Creacin de interfaces de usuario alternativas se vuelve mucho ms simple que podemos
reutilizar la lgica interna del juego completo.
Es mucho ms fcil y ms rpido para desarrollar una inteligencia artificial basada en una
representacin del juego interno de trabajar directamente en la interfaz de usuario.
Mantener significativas registros y la presentacin de juego estadsticas se hace ms fcil
Pero tambin hay desventajas:
Traduciendo entre la interfaz de usuario y una representacin del juego interno es ms difcil .
Vamos a aadir dos nuevas clases. El primero representa el juegos de estado interno y las
reglas. El segundo representa una pieza del juego. Vamos a echar un vistazo a la clase primera
pieza de juego. En el artculo anterior una pieza consisti en una imagen que representa la
pieza, la coordenadas X e Y donde mostrar la pieza, el color y el tipo. Vamos a dividir esta clase
en dos clases. Uno para la representacin interna y una para la interfaz grfica de usuario. Para
la representacin interna necesitaremos el color y el tipo. Tambin tenemos que saber dnde
est la pieza es. Esto se puede hacer de varias maneras. Vamos a mantenerlo simple y agregar
una variable de columna y la fila a la pieza. Tambin podramos haber creado algo (una nueva
clase o una matriz de dos dimensiones, etc) para representar a la junta, pero vamos a
mantenerlo simple por ahora. Tambin se introduce el concepto de captura de piezas. Por lo
tanto, otra variable es introduce en la clase de pieza que indica si la pieza ha sido capturado o
no. Tambin puede pensar en esto como un estado pieza en lugar de un estado de juego. Para
facilitar su uso se definira como una variable booleana.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
pblico de clase Pedazo {
privada int colores;
pblica esttica definitiva int Color_White = 0 ;
pblica esttica definitiva int Color_Black = 1 ;

privada int tipo;
pblica esttica definitiva int TYPE_ROOK = 1 ;
pblica esttica definitiva int TYPE_KNIGHT = 2 ;
pblica esttica definitiva int TYPE_BISHOP = 3 ;
pblica esttica definitiva int TYPE_QUEEN = 4 ;
pblica esttica definitiva int TYPE_KING = 5 ;
pblica esttica definitiva int TYPE_PAWN = 6 ;

/ / El ajedrez se juega sobre un tablero cuadrado de
/ / Ocho filas (denotadas con los nmeros 1 a 8)
/ / Y ocho columnas (indicado con las letras A a H)
privada int fila;

pblica esttica definitiva int ROW_1 = 0 ;
pblica esttica definitiva int ROW_2 = 1 ;
pblica esttica definitiva int ROW_3 = 2 ;
pblica esttica definitiva int ROW_4 = 3 ;
pblica esttica definitiva int ROW_5 = 4 ;
pblica esttica definitiva int ROW_6 = 5 ;
pblica esttica definitiva int ROW_7 = 6 ;
pblica esttica definitiva int ROW_8 = 7 ;

privada int columna;

pblica esttica definitiva int column_a = 0 ;
pblica esttica definitiva int COLUMN_B = 1 ;
pblica esttica definitiva int COLUMN_C = 2 ;
pblica esttica definitiva int COLUMN_D = 3 ;
pblica esttica definitiva int COLUMN_E = 4 ;
pblica esttica definitiva int COLUMN_F = 5 ;
pblica esttica definitiva int COLUMN_G = 6 ;
pblica esttica definitiva int COLUMN_H = 7 ;

privado boolean isCaptured = false ;
/ / ..
35
36
37
38
39
40
41
}
Para la interfaz de usuario se utilizar una referencia a la representacin interna subyacente y la
imagen y las coordenadas de esa imagen.
1
2
3
4
5
6
7
8
9
pblico de clase GuiPiece {

privado img Imagen;
privada int x;
privada int y;
privado PEDAZO;

/ / ..
}
Para convertir entre las coordenadas X e Y se utilizan en la interfaz de usuario y las columnas y
filas se utilizan en la representacin interna, se han creado varios mtodos de ayuda.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pblico de clase ChessGui extiende JPanel {
/ / ..
/ **
* Convertir columna lgico en coordenada x
* @ Param columna
* @ Return coordenada x de la columna
* /
pblico static int convertColumnToX ( int columna) {
volver PIECES_START_X + SQUARE_WIDTH * columna;
}

/ **
* Convertir fila lgica en coordenada
* @ Param fila
* @ Return coordenada de fila
* /
pblico static int convertRowToY ( int fila) {
volver PIECES_START_Y + SQUARE_HEIGHT * fila;
}

/ **
* Converso coordenada x en la columna lgica
* @ Param x
* @ Return columna lgico para la coordenada x
* /
pblico static int convertXToColumn ( int x) {
volver (x - DRAG_TARGET_SQUARE_START_X) / SQUARE_WIDTH;
}

/ **
* Convertir la coordenada y en fila lgica
27
28
29
30
31
32
33
34
35
36
37
38
* @ Param y
* @ Return fila lgica de la coordenada
* /
pblico static int convertYToRow ( int y) {
retorno (y - DRAG_TARGET_SQUARE_START_Y) / SQUARE_HEIGHT;
}
/ / ..
Estas funciones se utilizan, por ejemplo, para la visualizacin y restablecimiento de las imgenes
en la interfaz de usuario.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
pblico de clase GuiPiece {
/ / ..
pblica GuiPiece (Imagen img, pieza piezas) {
este . img = img;
esta unidad = pieza.;

este . resetToUnderlyingPiecePosition ();
}

/ **
* Mover la pieza gui nuevo a las coordenadas que
* Corresponden con la fila y la columna de la pieza subyacente
* /
pblico void resetToUnderlyingPiecePosition () {
este x = ChessGui.convertColumnToX (piece.getColumn ()).;
este . Y = ChessGui.convertRowToY (piece.getRow ());
}
/ / ..
}
La representacin interna del propio partido con el estado del juego y todas las piezas, se pone
en una nueva clase llamada Chessgame. Esta clase contiene principalmente la lgica para la
creacin del juego y las piezas en movimiento. Tambin proporciona mtodos para obtener
informacin sobre el estado actual de juegos y la ubicacin de las piezas. Tenga en cuenta que
no contiene ninguna informacin sobre la interfaz de usuario y no contiene ninguna dependencia
a las clases de GUI.
1
2
3
4
5
6
7
pblico de clase Chessgame {

privada int gamestate = GAME_STATE_WHITE;
pblica esttica definitiva int GAME_STATE_WHITE = 0 ;
pblica esttica definitiva int GAME_STATE_BLACK = 1 ;

/ / 0 = abajo, tamao = top
privadas pedazos Lista <Piece> = nuevo ArrayList <Piece> ();
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

/ **
* Juego initialize
* /
pblica Chessgame () {

/ / Crear y colocar las piezas
/ / Torre, caballo, alfil, reina, rey, obispo, caballero, y la torre
createAndAddPiece (Piece.COLOR_WHITE, Piece.TYPE_ROOK, Piece.ROW_1, Piece.COLUMN_A);
createAndAddPiece (Piece.COLOR_WHITE, Piece.TYPE_KNIGHT, Piece.ROW_1, Piece.COLUMN_B);
createAndAddPiece (Piece.COLOR_WHITE, Piece.TYPE_BISHOP, Piece.ROW_1, Piece.COLUMN_C);
createAndAddPiece (Piece.COLOR_WHITE, Piece.TYPE_QUEEN, Piece.ROW_1, Piece.COLUMN_D);
createAndAddPiece (Piece.COLOR_WHITE, Piece.TYPE_KING, Piece.ROW_1, Piece.COLUMN_E);
createAndAddPiece (Piece.COLOR_WHITE, Piece.TYPE_BISHOP, Piece.ROW_1, Piece.COLUMN_F);
createAndAddPiece (Piece.COLOR_WHITE, Piece.TYPE_KNIGHT, Piece.ROW_1, Piece.COLUMN_G);
createAndAddPiece (Piece.COLOR_WHITE, Piece.TYPE_ROOK, Piece.ROW_1, Piece.COLUMN_H);

/ / peones
int CurrentColumn = Piece.COLUMN_A;
para ( int i = 0 ; i < 8 ; i + +) {
createAndAddPiece (Piece.COLOR_WHITE, Piece.TYPE_PAWN, Piece.ROW_2, CurrentColumn);
CurrentColumn + +;
}

createAndAddPiece (Piece.COLOR_BLACK, Piece.TYPE_ROOK, Piece.ROW_8, Piece.COLUMN_A);
createAndAddPiece (Piece.COLOR_BLACK, Piece.TYPE_KNIGHT, Piece.ROW_8, Piece.COLUMN_B);
createAndAddPiece (Piece.COLOR_BLACK, Piece.TYPE_BISHOP, Piece.ROW_8, Piece.COLUMN_C);
createAndAddPiece (Piece.COLOR_BLACK, Piece.TYPE_QUEEN, Piece.ROW_8, Piece.COLUMN_D);
createAndAddPiece (Piece.COLOR_BLACK, Piece.TYPE_KING, Piece.ROW_8, Piece.COLUMN_E);
createAndAddPiece (Piece.COLOR_BLACK, Piece.TYPE_BISHOP, Piece.ROW_8, Piece.COLUMN_F);
createAndAddPiece (Piece.COLOR_BLACK, Piece.TYPE_KNIGHT, Piece.ROW_8, Piece.COLUMN_G);
createAndAddPiece (Piece.COLOR_BLACK, Piece.TYPE_ROOK, Piece.ROW_8, Piece.COLUMN_H);

/ / peones
CurrentColumn = Piece.COLUMN_A;
para ( int i = 0 ; i < 8 ; i + +) {
createAndAddPiece (Piece.COLOR_BLACK, Piece.TYPE_PAWN, Piece.ROW_7, CurrentColumn);
CurrentColumn + +;
}
}

/ **
* Crear instancia pieza y aadirlo a la lista interna de piezas
*
* @ Param en colores de Pieces.COLOR_ ..
* @ Param tipo sobre de Pieces.TYPE_ ..
* @ Param fila sobre de Pieces.ROW_ ..
* @ Param columna sobre de Pieces.COLUMN_ ..
* /
privado void createAndAddPiece ( int color, int tipo, int fila, int columna) {
PEDAZO = nueva pieza (color, tipo, fila, columna);
este . pieces.add (pieza);
este . movePiece (pieza, fila, columna);
}

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/ **
* Mover pieza a la ubicacin especificada. Si est ocupada la ubicacin de destino
* Por una pieza oponente, esa pieza se marca como 'capturado'
* @ Param piece la pieza a mover
* @ Param fila la fila de destino (Piece.ROW_ ..)
* @ Param columna de la columna de destino (Piece.COLUMN_ ..)
* /
pblico void movePiece (pieza Piece, int fila, int columna) {
/ / Comprobar si el movimiento es la captura de una pieza opponend
int opponentColor = (piece.getColor () == Piece.COLOR_BLACK Piece.COLOR_WHITE:?
Piece.COLOR_BLACK);
si (isNonCapturedPieceAtLocation (opponentColor, fila, columna)) {
OpponentPiece pieza = getNonCapturedPieceAtLocation (fila, columna);
opponentPiece.isCaptured ( verdadero );
}

piece.setRow (fila);
piece.setColumn (columna);
}

/ **
* Devuelve la primera pieza en el lugar especificado que no est marcado
* Como 'capturado'.
* @ Param fila uno de Piece.ROW_ ..
* @ Param columna uno de Piece.COLUMN_ ..
* @ Return la primera pieza que no se reflejan en la ubicacin especificada
* /
privado Pedazo getNonCapturedPieceAtLocation ( int fila, int columna) {
de (pieza por pieza: este . piezas) {
si (piece.getRow () == fila
&& Piece.getColumn (columna) ==
&& Piece.isCaptured () == false ) {
volver pieza;
}
}
devolver nulo ;
}

/ **
* Comprueba si hay una pieza en el lugar especificado que no es
* Marcados como 'capturado' y tiene el color especificado.
* @ Param color de uno de Piece.COLOR_ ..
* @ Param fila uno de Piece.ROW_ ..
* @ Param columna sobre de Piece.COLUMN_ ..
* @ Return true, si la ubicacin contiene una pieza que no se reflejan de la
* Color especificado
* /
privado boolean isNonCapturedPieceAtLocation ( int color, int fila, int columna) {
de (pieza por pieza: este . piezas) {
si (piece.getRow () == fila
&& Piece.getColumn (columna) ==
&& Piece.isCaptured () == false
&& Piece.getColor () == de color) {
devolver cierto ;
}
}
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
volver falsa ;
}

/ **
* @ Return estado actual del juego (una de ChessGame.GAME_STATE_ ..)
* /
pblica int getGameState () {
devolver este gamestate.;
}

/ **
* @ Return la lista interna de piezas
* /
pblica Lista <Piece> getPieces () {
devolver este pedazos.;
}

/ **
* Cambia el estado de juego de ChessGame.GAME_STATE_WHITE a
* ChessGame.GAME_STATE_BLACK y viceversa.
* /
pblico void changeGameState () {
interruptor ( esto . gamestate) {
caso GAME_STATE_BLACK:
este . gamestate = GAME_STATE_WHITE;
romper ;
caso GAME_STATE_WHITE:
este . gamestate = GAME_STATE_BLACK;
romper ;
default :
arrojar nueva IllegalStateException ( "estado del juego desconocido:" + este .
gamestate);
}
}

}
146
147
148
149
150
151
152
153
La vieja clase ChessGui ha sido adaptado para utilizar la nueva clase Chessgame. La creacin de
juego y piezas ha convertido en mucho ms simple ahora.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
pblico de clase ChessGui extiende JPanel {

/ / ..
pblica ChessGui () {
/ / ..

/ / Crear el juego de ajedrez
este . Chessgame = nueva Chessgame ();

Pieces / / juego envoltura en su representacin grfica
de (pieza por pieza: este . chessGame.getPieces ()) {
createAndAddGuiPiece (pieza);
}
}

/ **
* Crear una pieza del juego
*
* @ Param color de color constante
* Platea @ param constante
* @ Param posicin xx de la esquina superior izquierda
* Posicin yy @ param de la esquina superior izquierda
* /
privado void createAndAddGuiPiece (pieza piezas) {
Image img = esto . getImageForPiece (piece.getColor (),
piece.getType ());
GuiPiece guiPiece = nueva GuiPiece (img, pieza);
este . guiPieces.add (guiPiece);
}

/ **
* Cambia entre los diferentes estados del juego
* /
pblico void changeGameState () {
este . chessGame.changeGameState ();
este . lblGameState.setText ( este getGameStateAsText ().);
}
/ / ..
}
37
38
La nica cosa que tiene mucho ms complicado es la conversin entre coordenadas en la
pantalla y los lugares utilizados por las clases de juego internas. Sin embargo, una vez que se
hace esto, somos mucho ms flexible.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
pblico de clase ChessGui extiende JPanel {

/ / ..
/ **
* Convertir columna lgico en coordenada x
* @ Param columna
* @ Return coordenada x de la columna
* /
pblico static int convertColumnToX ( int columna) {
volver PIECES_START_X + SQUARE_WIDTH * columna;
}

/ **
* Convertir fila lgica en coordenada
* @ Param fila
* @ Return coordenada de fila
* /
pblico static int convertRowToY ( int fila) {
volver PIECES_START_Y + SQUARE_HEIGHT * (Piece.ROW_8 - fila);
}

/ **
* Converso coordenada x en la columna lgica
* @ Param x
* @ Return columna lgico para la coordenada x
* /
pblico static int convertXToColumn ( int x) {
volver (x - DRAG_TARGET_SQUARE_START_X) / SQUARE_WIDTH;
}

/ **
* Convertir la coordenada y en fila lgica
* @ Param y
* @ Return fila lgica de la coordenada
* /
pblico static int convertYToRow ( int y) {
volver Piece.ROW_8 - (y - DRAG_TARGET_SQUARE_START_Y) / SQUARE_HEIGHT;
}

/ **
* El cambio de ubicacin de la pieza dada, si la ubicacin es vlida.
* Si la ubicacin no es vlida, mueva la pieza de nuevo a su estado original
* Posicin.
* @ Param dragPiece
* @ Param x
* @ Param y
* /
pblico void setNewPieceLocation (GuiPiece dragPiece, int x, int y) {
int targetRow = ChessGui.convertYToRow (y);
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
int targetColumn = ChessGui.convertXToColumn (x);

si (targetRow <Piece.ROW_1 | | targetRow> Piece.ROW_8 | | targetColumn <Piece.COLUMN_A | | targetColumn>
Piece.COLUMN_H) {
/ / Restablecer la posicin pieza si movimiento no es vlida
dragPiece.resetToUnderlyingPiecePosition ();

} ms {
/ / Cambio de modelo y de actualizacin pieza gui despus
System.out.println ( "pieza mvil a" + targetRow + "/" + targetColumn);
este . chessGame.movePiece (
dragPiece.getPiece (). getRow (), dragPiece.getPiece (). GetColumn ()
, TargetRow, targetColumn);
dragPiece.resetToUnderlyingPiecePosition ();
}
}
/ / ..
}
Eso es todo. En el siguiente artculo vamos a mostrar uno de los beneficios de la nueva
estructura del cdigo de la implementacin de un interfaz de usuario basado en la consola en la
parte superior de nuestras clases de lgica de juego interior.

En este artculo vamos a echar un vistazo ms de cerca la aplicacin de las reglas del
juego. Porque nos separamos de la lgica de la vista de la lgica del juego en uno de los
artculos anteriores, la implementacin de la aplicacin de la regla es ms fcil que usted podra
pensar en esta etapa.

Esta es la quinta parte de una serie de artculos acerca de la programacin de un juego de
ajedrez en Java con Swing. Como todos los artculos se acumulan unos sobre otros, le animo a
que tambin echar un vistazo a los artculos anteriores de esta serie ( Chess01: Arrastrar las
piezas del juego , Chess02: Presentacin del estado del juego , Chess03: Separar vista y la
lgica , Chess04: Implementacin de una interfaz de usuario alternativa ).
Hay varias formas de implementar la aplicacin de la regla. En este ejemplo he optado por
aplicar la lgica de validacin movimiento en una sola clase llamada MoveValidator. La clase
MoveValidator cubre los movimientos de ajedrez bsicos para cada pieza. Sin embargo, no cubre
todas las reglas, ya que el enfoque del artculo es sobre el concepto general de la aplicacin de
las reglas del juego y no en la implementacin de un juego de ajedrez con todas las
funciones. Reglas que faltan son, por ejemplo tablas, jaque mate, en passant, el enroque, ...
Para habilitar la validacin de movimiento simplemente se aade cuatro lneas al principio de
nuestra movePiece (mtodo) en la clase Chessgame.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
pblico de clase Chessgame {

/ / ..
/ **
* Mover pieza a la ubicacin especificada. Si est ocupada la ubicacin de destino
* Por una pieza oponente, esa pieza se marca como 'capturado'
* @ Param sourceRow la fila de origen (Piece.ROW_ ..) de la pieza a mover
* @ Param SourceColumn columna de origen (Piece.COLUMN_ ..) de la pieza a mover
* @ Param targetRow la fila de destino (Piece.ROW_ ..)
* @ Param targetColumn columna de destino (Piece.COLUMN_ ..)
* /
pblico void movePiece ( int sourceRow, int SourceColumn, int targetRow, int targetColumn)
{

si (! esto . moveValidator.isMoveValid (sourceRow, SourceColumn, targetRow,
targetColumn)) {
System.out.println ( "mover vlido" );
volver ;
}

PEDAZO = getNonCapturedPieceAtLocation (sourceRow, SourceColumn);

/ / Comprobar si el movimiento es la captura de una pieza oponente
int opponentColor = (piece.getColor () == Piece.COLOR_BLACK Piece.COLOR_WHITE:?
Piece.COLOR_BLACK);
si (isNonCapturedPieceAtLocation (opponentColor, targetRow, targetColumn)) {
OpponentPiece pieza = getNonCapturedPieceAtLocation (targetRow, targetColumn);
opponentPiece.isCaptured ( verdadero );
}

piece.setRow (targetRow);
piece.setColumn (targetColumn);

este . changeGameState ();
}
/ / ..

}
El mtodo isValidMove () de la clase MoveValidator comprobar primero si existe la una pieza en
la ubicacin de origen. Si es as, comprueba si el color es vincular el estado actual del
juego. Entonces es valida si la ubicacin de destino es vlido. Despus, el movimiento se analiz
adicionalmente por llamar a un mtodo de validacin que corresponde al tipo de pieza en
movimiento. Si an no existe un problema con el movimiento, debemos comprobar por resultado
situaciones de estancamiento y jaque mate. Sin embargo, esto se ha quedado fuera de este
artculo.
1
2
pblico de clase MoveValidator {
/ / ..
/ **
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
* Comprueba si el movimiento especificado es vlido
* @ Param sourceRow
* @ Param SourceColumn
* @ Param targetRow
* @ Param targetColumn
* @ Return true si movimiento es vlido, false si movimiento no es vlida
* /
pblica boolean isMoveValid ( int sourceRow,
int SourceColumn, int targetRow, int targetColumn) {

sourcePiece = chessGame.getNonCapturedPieceAtLocation (sourceRow, SourceColumn);
targetPiece = esta chessGame.getNonCapturedPieceAtLocation (targetRow, targetColumn).;

Pedazo / / origen no existe
si (sourcePiece == NULL ) {
System.out.println ( "ninguna pieza de origen" );
volver falsa ;
}

Pedazo / / fuente tiene el color correcto?
si (sourcePiece.getColor () == Piece.COLOR_WHITE
&& este . chessGame.getGameState () == ChessGame.GAME_STATE_WHITE) {
/ / Ok
} dems si (sourcePiece.getColor () == Piece.COLOR_BLACK
&& este . chessGame.getGameState () == ChessGame.GAME_STATE_BLACK) {
/ / Ok
} ms {
System.out.println ( "no es tu turno" );
volver falsa ;
}

/ / Comprobar si la ubicacin de destino dentro de los lmites
si (targetRow <Piece.ROW_1 | | targetRow> Piece.ROW_8
| | TargetColumn <Piece.COLUMN_A | | targetColumn> Piece.COLUMN_H) {
System.out.println ( "fila de destino o de la columna fuera de alcance" );
volver falsa ;
}

/ / Validar pieza reglas de movimiento
boolean validPieceMove = false ;
interruptor (sourcePiece.getType ()) {
caso Piece.TYPE_BISHOP:
validPieceMove = isValidBishopMove (sourceRow, SourceColumn, targetRow,
targetColumn); romper ;
caso Piece.TYPE_KING:
validPieceMove = isValidKingMove (sourceRow, SourceColumn, targetRow,
targetColumn); romper ;
caso Piece.TYPE_KNIGHT:
validPieceMove = isValidKnightMove (sourceRow, SourceColumn, targetRow,
targetColumn); romper ;
caso Piece.TYPE_PAWN:
validPieceMove = isValidPawnMove (sourceRow, SourceColumn, targetRow,
targetColumn); romper ;
caso Piece.TYPE_QUEEN:
validPieceMove = isValidQueenMove (sourceRow, SourceColumn, targetRow,
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
targetColumn); romper ;
caso Piece.TYPE_ROOK:
validPieceMove = isValidRookMove (sourceRow, SourceColumn, targetRow,
targetColumn); romper ;
default : descanso ;
}
si (! validPieceMove) {
volver falsa ;
} ms {
/ / Ok
}


/ / Manipulador punto muerto y el jaque mate
/ / ..

devolver cierto ;
}
/ / ..
}
He aqu un ejemplo del mtodo de validacin para el tipo de pieza 'Knight'.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pblico de clase MoveValidator {
/ / ..
privado boolean isValidKnightMove ( int sourceRow, int SourceColumn, int targetRow, int
targetColumn) {
/ / El caballo se mueve a cualquiera de las plazas ms cercanas que no estn en el mismo rango,
/ / Archivo o diagonal, por lo tanto el movimiento forma una "L" en forma de dos cuadrados de largo y una
/ / Cuadrado de ancho. El caballo es la nica pieza que puede saltar sobre otras piezas.

/ / Ubicacin de destino posible?
si (isTargetLocationFree () | | isTargetLocationCaptureable ()) {
/ / Ok
} ms {
System.out.println ( "lugar de destino no es gratis y no captureable" );
volver falsa ;
}

si (sourceRow + 2 == targetRow && SourceColumn + 1 == targetColumn) {
/ / Sube encima de la derecha
devolver cierto ;
} dems si (sourceRow + 1 == targetRow && SourceColumn + 2 == targetColumn) {
/ / Sube un derecho justo
devolver cierto ;
} dems si (sourceRow- 1 == targetRow && SourceColumn + 2 == targetColumn) {
/ / Mover hacia abajo a la derecha a la derecha
devolver cierto ;
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
} dems si (sourceRow- 2 == targetRow && SourceColumn + 1 == targetColumn) {
/ / Bajar abajo a la derecha
devolver cierto ;
} dems si (sourceRow- 2 == targetRow && SourceColumn- 1 == targetColumn) {
/ / Bajar abajo a la izquierda
devolver cierto ;
} dems si (sourceRow- 1 == targetRow && SourceColumn- 2 == targetColumn) {
/ / Mover hacia abajo izquierda izquierda
devolver cierto ;
} dems si (sourceRow + 1 == targetRow && SourceColumn- 2 == targetColumn) {
/ / Sube izquierda izquierda
devolver cierto ;
} dems si (sourceRow + 2 == targetRow && SourceColumn- 1 == targetColumn) {
/ / Sube arriba izquierda
devolver cierto ;
} ms {
volver falsa ;
}
}
/ / ..
}
El chessGame.changeGameState () mtodo se ha ampliado tambin. Se comprueba ahora si se
ha alcanzado el estado final de la partida.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
pblico de clase Chessgame {
/ / ..
/ **
* Cambia el estado del juego en funcin de la situacin actual junta directiva.
* /
pblico void changeGameState () {

/ / Comprobar si se ha alcanzado la condicin final del juego
/ /
Si ( esto . isGameEndConditionReached ()) {

Si ( esto . gamestate == ChessGame.GAME_STATE_BLACK) {
System.out.println ( "Se acab el juego Negro gan!" );
} ms {
System.out.println ( "Game over Blanco gan!" );
}

este . gamestate = ChessGame.GAME_STATE_END;
volver ;
}

interruptor ( esto . gamestate) {
caso GAME_STATE_BLACK:
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
este . gamestate = GAME_STATE_WHITE;
romper ;
caso GAME_STATE_WHITE:
este . gamestate = GAME_STATE_BLACK;
romper ;
caso GAME_STATE_END:
/ / No cambie ms
romper ;
default :
arrojar nueva IllegalStateException ( "estado del juego desconocido:" + este .
gamestate);
}
}

/ **
* Comprobar si se cumple la condicin de fin de juegos: Un color tiene un rey capturado
*
* @ Return true si se cumple la condicin de fin de juego
* /
privado boolean isGameEndConditionReached () {
de (pieza por pieza: este . piezas) {
si (piece.getType () == Piece.TYPE_KING && piece.isCaptured ()) {
devolver cierto ;
} ms {
/ / Continuar la iteracin
}
}

volver falsa ;
}
/ / ..
}
Adems de los cambios mencionados cambios se hicieron para la interfaz de usuario para
manejar el nuevo estado de fin de juego.
En el siguiente artculo vamos a echar un vistazo a la forma de poner de relieve todas las
ubicaciones de destino vlidas para una pieza del juego .

You might also like