diff options
Diffstat (limited to 'src/FourByFour')
-rw-r--r-- | src/FourByFour/BigCube.java | 140 | ||||
-rw-r--r-- | src/FourByFour/Board.java | 2310 | ||||
-rw-r--r-- | src/FourByFour/Canvas2D.java | 92 | ||||
-rw-r--r-- | src/FourByFour/Cube.java | 131 | ||||
-rw-r--r-- | src/FourByFour/Cylinder.java | 114 | ||||
-rw-r--r-- | src/FourByFour/FourByFour.html | 15 | ||||
-rw-r--r-- | src/FourByFour/FourByFour.java | 884 | ||||
-rw-r--r-- | src/FourByFour/FourByFour_plugin.html | 39 | ||||
-rw-r--r-- | src/FourByFour/ID.java | 59 | ||||
-rw-r--r-- | src/FourByFour/PickDragBehavior.java | 216 | ||||
-rw-r--r-- | src/FourByFour/Poles.java | 80 | ||||
-rw-r--r-- | src/FourByFour/Positions.java | 311 | ||||
-rw-r--r-- | src/FourByFour/README | 47 | ||||
-rw-r--r-- | src/FourByFour/build.xml | 66 | ||||
-rw-r--r-- | src/FourByFour/instructions.txt | 93 | ||||
-rw-r--r-- | src/FourByFour/scores.txt | 20 |
16 files changed, 4617 insertions, 0 deletions
diff --git a/src/FourByFour/BigCube.java b/src/FourByFour/BigCube.java new file mode 100644 index 0000000..d6fda52 --- /dev/null +++ b/src/FourByFour/BigCube.java @@ -0,0 +1,140 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import java.applet.Applet; +import java.awt.event.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +/** + * Class BigCube + * + * Description: Creates the "big" cube used to mark the computer's + * position. + * + * Version: 1.0 + * + * Copyright (C) 1998 Sun Microsystems, Inc. All Rights Reserved. + */ +public class BigCube extends Object { + + private Shape3D shape3D; + + private static final float[] verts = { + // Front Face + 5.0f, -5.0f, 5.0f, 5.0f, 5.0f, 5.0f, + -5.0f, 5.0f, 5.0f, -5.0f, -5.0f, 5.0f, + // Back Face + -5.0f, -5.0f, -5.0f, -5.0f, 5.0f, -5.0f, + 5.0f, 5.0f, -5.0f, 5.0f, -5.0f, -5.0f, + // Right Face + 5.0f, -5.0f, -5.0f, 5.0f, 5.0f, -5.0f, + 5.0f, 5.0f, 5.0f, 5.0f, -5.0f, 5.0f, + // Left Face + -5.0f, -5.0f, 5.0f, -5.0f, 5.0f, 5.0f, + -5.0f, 5.0f, -5.0f, -5.0f, -5.0f, -5.0f, + // Top Face + 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, -5.0f, + -5.0f, 5.0f, -5.0f, -5.0f, 5.0f, 5.0f, + // Bottom Face + -5.0f, -5.0f, 5.0f, -5.0f, -5.0f, -5.0f, + 5.0f, -5.0f, -5.0f, 5.0f, -5.0f, 5.0f, + }; + + private static final float[] normals = { + // Front Face + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + // Back Face + 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, + // Right Face + 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + // Left Face + -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + // Top Face + 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + // Bottom Face + 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, + }; + + public BigCube(Appearance appearance) { + + QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES | + QuadArray.NORMALS ); + quadArray.setCoordinates(0, verts); + quadArray.setNormals(0, normals); + + shape3D = new Shape3D(quadArray, appearance); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + } + + public BigCube(Appearance appearance, float size) { + + QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES | + QuadArray.NORMALS ); + + for (int i=0; i<72; i++) verts[i] *= size; + + quadArray.setCoordinates(0, verts); + quadArray.setNormals(0, normals); + + shape3D = new Shape3D(quadArray, appearance); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + } + + public Shape3D getChild() { + return shape3D; + } +} diff --git a/src/FourByFour/Board.java b/src/FourByFour/Board.java new file mode 100644 index 0000000..e0d2b0a --- /dev/null +++ b/src/FourByFour/Board.java @@ -0,0 +1,2310 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import java.awt.*; + +/** + * Class: Board + * + * Description: Handles all logic with respect to play. Also renders + * the 2D window. + * + * Version: 1.1 + * + */ +class Board { + + final static int UNOCCUPIED = 0; + final static int HUMAN = 1; + final static int MACHINE = 2; + final static int END = 3; + + private int[] moves; + private int[] occupied; + private int[][] combinations; + private int[][] outside_four; + private int[][] inside_four; + private int[][] faces; + private int[][] pos_to_comb; + private int[][] best_picks; + private int num_points; + private int num_balls; + private int num_polygons; + private int num_pt_indexes; + private int num_normal_indexes; + private int pt_start; + private int color_index; + private int width; + private int height; + private int center_x; + private int center_y; + private int player; + private int skill_level; + private int outside_four_index; + private int inside_four_index; + private int face_index; + private int nmoves; + private int current_face; + private int min = 1000; + private int max = 0; + private long[] sort_array; + private long time; + private long beg_time; + private long end_time; + private Color[] color_ramp; + private Color background; + private Color label_color; + private Color red; + private Color blue; + private Color white; + private Color gray; + private Color yellow; + private double max_dist; + private FourByFour panel; + private boolean debug; + private boolean outside_four_flag; + private boolean inside_four_flag; + private boolean face_flag; + private boolean label_flag; + private boolean block_chair_flag; + private boolean undoFlag; + private boolean[] highlight; + private int block_chair_next_move; + private int block_chair_face; + private Positions positions; + private Canvas2D canvas; + + Board (FourByFour panel, Positions positions, int width, int height) { + + // Set the debug state. + debug = false; + + // Store arguments + this.width = width; + this.height = height; + this.panel = panel; + this.positions = positions; + + // Initialize flags + label_flag = false; + outside_four_flag = false; + inside_four_flag = false; + block_chair_flag = false; + undoFlag = false; + + // Total number of board positions. + num_points = 64; + + // Allocate the logic arrays. + moves = new int[64]; + occupied = new int[64]; + combinations = new int[76][7]; + outside_four = new int[18][6]; + inside_four = new int[18][6]; + faces = new int[18][18]; + pos_to_comb = new int[64][8]; + best_picks = new int[64][8]; + highlight = new boolean[18]; + + // Initialize the logic arrays. + init_combinations(); + init_faces(); + init_outside_four(); + init_inside_four(); + + // Set the player with the first move. + player = HUMAN; + + // Set the default skill level. + skill_level = 4; + + // Initialize the number of moves. + nmoves = 0; + + // Define colors + background = new Color(13, 13, 51); + red = new Color(230, 26, 51); + blue = new Color(51, 51, 230); + white = new Color(255, 255, 255); + gray = new Color(240, 240, 240); + yellow = new Color(240, 240, 0); + + // Record the start time + beg_time = System.currentTimeMillis(); + } + + public void setCanvas(Canvas2D canvas) { + this.canvas = canvas; + } + + public void init_combinations () { + + // The combination array contains all possible winning combinations. + // + // Each combination has the following format: + // + // combinations[x][0] = status: 0 = no player has selected positons in this row + // -1 = both players have men in this row + // 1 to 4 = number of positions occupied by player + // + // combinations[x][1] = player who owns this row (valid only if status = 1-4) + // combinations[x][2] = postion that define the row + // combinations[x][3] = postion that define the row + // combinations[x][4] = postion that define the row + // combinations[x][5] = postion that define the row + + // Horizontal, Z + + combinations[ 0][0] = 0; combinations[ 1][0] = 0; combinations[ 2][0] = 0; combinations[ 3][0] = 0; + combinations[ 0][1] = 0; combinations[ 1][1] = 0; combinations[ 2][1] = 0; combinations[ 3][1] = 0; + combinations[ 0][2] = 0; combinations[ 1][2] = 4; combinations[ 2][2] = 8; combinations[ 3][2] = 12; + combinations[ 0][3] = 1; combinations[ 1][3] = 5; combinations[ 2][3] = 9; combinations[ 3][3] = 13; + combinations[ 0][4] = 2; combinations[ 1][4] = 6; combinations[ 2][4] = 10; combinations[ 3][4] = 14; + combinations[ 0][5] = 3; combinations[ 1][5] = 7; combinations[ 2][5] = 11; combinations[ 3][5] = 15; + + combinations[ 4][0] = 0; combinations[ 5][0] = 0; combinations[ 6][0] = 0; combinations[ 7][0] = 0; + combinations[ 4][1] = 0; combinations[ 5][1] = 0; combinations[ 6][1] = 0; combinations[ 7][1] = 0; + combinations[ 4][2] = 16; combinations[ 5][2] = 20; combinations[ 6][2] = 24; combinations[ 7][2] = 28; + combinations[ 4][3] = 17; combinations[ 5][3] = 21; combinations[ 6][3] = 25; combinations[ 7][3] = 29; + combinations[ 4][4] = 18; combinations[ 5][4] = 22; combinations[ 6][4] = 26; combinations[ 7][4] = 30; + combinations[ 4][5] = 19; combinations[ 5][5] = 23; combinations[ 6][5] = 27; combinations[ 7][5] = 31; + + combinations[ 8][0] = 0; combinations[ 9][0] = 0; combinations[10][0] = 0; combinations[11][0] = 0; + combinations[ 8][1] = 0; combinations[ 9][1] = 0; combinations[10][1] = 0; combinations[11][1] = 0; + combinations[ 8][2] = 32; combinations[ 9][2] = 36; combinations[10][2] = 40; combinations[11][2] = 44; + combinations[ 8][3] = 33; combinations[ 9][3] = 37; combinations[10][3] = 41; combinations[11][3] = 45; + combinations[ 8][4] = 34; combinations[ 9][4] = 38; combinations[10][4] = 42; combinations[11][4] = 46; + combinations[ 8][5] = 35; combinations[ 9][5] = 39; combinations[10][5] = 43; combinations[11][5] = 47; + + combinations[12][0] = 0; combinations[13][0] = 0; combinations[14][0] = 0; combinations[15][0] = 0; + combinations[12][1] = 0; combinations[13][1] = 0; combinations[14][1] = 0; combinations[15][1] = 0; + combinations[12][2] = 48; combinations[13][2] = 52; combinations[14][2] = 56; combinations[15][2] = 60; + combinations[12][3] = 49; combinations[13][3] = 53; combinations[14][3] = 57; combinations[15][3] = 61; + combinations[12][4] = 50; combinations[13][4] = 54; combinations[14][4] = 58; combinations[15][4] = 62; + combinations[12][5] = 51; combinations[13][5] = 55; combinations[14][5] = 59; combinations[15][5] = 63; + + // Vertical, Z + + combinations[16][0] = 0; combinations[17][0] = 0; combinations[18][0] = 0; combinations[19][0] = 0; + combinations[16][1] = 0; combinations[17][1] = 0; combinations[18][1] = 0; combinations[19][1] = 0; + combinations[16][2] = 0; combinations[17][2] = 1; combinations[18][2] = 2; combinations[19][2] = 3; + combinations[16][3] = 4; combinations[17][3] = 5; combinations[18][3] = 6; combinations[19][3] = 7; + combinations[16][4] = 8; combinations[17][4] = 9; combinations[18][4] = 10; combinations[19][4] = 11; + combinations[16][5] = 12; combinations[17][5] = 13; combinations[18][5] = 14; combinations[19][5] = 15; + + combinations[20][0] = 0; combinations[21][0] = 0; combinations[22][0] = 0; combinations[23][0] = 0; + combinations[20][1] = 0; combinations[21][1] = 0; combinations[22][1] = 0; combinations[23][1] = 0; + combinations[20][2] = 16; combinations[21][2] = 17; combinations[22][2] = 18; combinations[23][2] = 19; + combinations[20][3] = 20; combinations[21][3] = 21; combinations[22][3] = 22; combinations[23][3] = 23; + combinations[20][4] = 24; combinations[21][4] = 25; combinations[22][4] = 26; combinations[23][4] = 27; + combinations[20][5] = 28; combinations[21][5] = 29; combinations[22][5] = 30; combinations[23][5] = 31; + + combinations[24][0] = 0; combinations[25][0] = 0; combinations[26][0] = 0; combinations[27][0] = 0; + combinations[24][1] = 0; combinations[25][1] = 0; combinations[26][1] = 0; combinations[27][1] = 0; + combinations[24][2] = 32; combinations[25][2] = 33; combinations[26][2] = 34; combinations[27][2] = 35; + combinations[24][3] = 36; combinations[25][3] = 37; combinations[26][3] = 38; combinations[27][3] = 39; + combinations[24][4] = 40; combinations[25][4] = 41; combinations[26][4] = 42; combinations[27][4] = 43; + combinations[24][5] = 44; combinations[25][5] = 45; combinations[26][5] = 46; combinations[27][5] = 47; + + combinations[28][0] = 0; combinations[29][0] = 0; combinations[30][0] = 0; combinations[31][0] = 0; + combinations[28][1] = 0; combinations[29][1] = 0; combinations[30][1] = 0; combinations[31][1] = 0; + combinations[28][2] = 48; combinations[29][2] = 49; combinations[30][2] = 50; combinations[31][2] = 51; + combinations[28][3] = 52; combinations[29][3] = 53; combinations[30][3] = 54; combinations[31][3] = 55; + combinations[28][4] = 56; combinations[29][4] = 57; combinations[30][4] = 58; combinations[31][4] = 59; + combinations[28][5] = 60; combinations[29][5] = 61; combinations[30][5] = 62; combinations[31][5] = 63; + + // Diagonal, Z + + combinations[32][0] = 0; combinations[33][0] = 0; combinations[34][0] = 0; combinations[35][0] = 0; + combinations[32][1] = 0; combinations[33][1] = 0; combinations[34][1] = 0; combinations[35][1] = 0; + combinations[32][2] = 0; combinations[33][2] = 16; combinations[34][2] = 32; combinations[35][2] = 48; + combinations[32][3] = 5; combinations[33][3] = 21; combinations[34][3] = 37; combinations[35][3] = 53; + combinations[32][4] = 10; combinations[33][4] = 26; combinations[34][4] = 42; combinations[35][4] = 58; + combinations[32][5] = 15; combinations[33][5] = 31; combinations[34][5] = 47; combinations[35][5] = 63; + + combinations[36][0] = 0; combinations[37][0] = 0; combinations[38][0] = 0; combinations[39][0] = 0; + combinations[36][1] = 0; combinations[37][1] = 0; combinations[38][1] = 0; combinations[39][1] = 0; + combinations[36][2] = 3; combinations[37][2] = 19; combinations[38][2] = 35; combinations[39][2] = 51; + combinations[36][3] = 6; combinations[37][3] = 22; combinations[38][3] = 38; combinations[39][3] = 54; + combinations[36][4] = 9; combinations[37][4] = 25; combinations[38][4] = 41; combinations[39][4] = 57; + combinations[36][5] = 12; combinations[37][5] = 28; combinations[38][5] = 44; combinations[39][5] = 60; + + // Horizontal, X + + combinations[40][0] = 0; combinations[41][0] = 0; combinations[42][0] = 0; combinations[43][0] = 0; + combinations[40][1] = 0; combinations[41][1] = 0; combinations[42][1] = 0; combinations[43][1] = 0; + combinations[40][2] = 51; combinations[41][2] = 55; combinations[42][2] = 59; combinations[43][2] = 63; + combinations[40][3] = 35; combinations[41][3] = 39; combinations[42][3] = 43; combinations[43][3] = 47; + combinations[40][4] = 19; combinations[41][4] = 23; combinations[42][4] = 27; combinations[43][4] = 31; + combinations[40][5] = 3; combinations[41][5] = 7; combinations[42][5] = 11; combinations[43][5] = 15; + + combinations[44][0] = 0; combinations[45][0] = 0; combinations[46][0] = 0; combinations[47][0] = 0; + combinations[44][1] = 0; combinations[45][1] = 0; combinations[46][1] = 0; combinations[47][1] = 0; + combinations[44][2] = 50; combinations[45][2] = 54; combinations[46][2] = 58; combinations[47][2] = 62; + combinations[44][3] = 34; combinations[45][3] = 38; combinations[46][3] = 42; combinations[47][3] = 46; + combinations[44][4] = 18; combinations[45][4] = 22; combinations[46][4] = 26; combinations[47][4] = 30; + combinations[44][5] = 2; combinations[45][5] = 6; combinations[46][5] = 10; combinations[47][5] = 14; + + combinations[48][0] = 0; combinations[49][0] = 0; combinations[50][0] = 0; combinations[51][0] = 0; + combinations[48][1] = 0; combinations[49][1] = 0; combinations[50][1] = 0; combinations[51][1] = 0; + combinations[48][2] = 49; combinations[49][2] = 53; combinations[50][2] = 57; combinations[51][2] = 61; + combinations[48][3] = 33; combinations[49][3] = 37; combinations[50][3] = 41; combinations[51][3] = 45; + combinations[48][4] = 17; combinations[49][4] = 21; combinations[50][4] = 25; combinations[51][4] = 29; + combinations[48][5] = 1; combinations[49][5] = 5; combinations[50][5] = 9; combinations[51][5] = 13; + + combinations[52][0] = 0; combinations[53][0] = 0; combinations[54][0] = 0; combinations[55][0] = 0; + combinations[52][1] = 0; combinations[53][1] = 0; combinations[54][1] = 0; combinations[55][1] = 0; + combinations[52][2] = 48; combinations[53][2] = 52; combinations[54][2] = 56; combinations[55][2] = 60; + combinations[52][3] = 32; combinations[53][3] = 36; combinations[54][3] = 40; combinations[55][3] = 44; + combinations[52][4] = 16; combinations[53][4] = 20; combinations[54][4] = 24; combinations[55][4] = 28; + combinations[52][5] = 0; combinations[53][5] = 4; combinations[54][5] = 8; combinations[55][5] = 12; + + // Diagonal, X + + combinations[56][0] = 0; combinations[57][0] = 0; combinations[58][0] = 0; combinations[59][0] = 0; + combinations[56][1] = 0; combinations[57][1] = 0; combinations[58][1] = 0; combinations[59][1] = 0; + combinations[56][2] = 51; combinations[57][2] = 50; combinations[58][2] = 49; combinations[59][2] = 48; + combinations[56][3] = 39; combinations[57][3] = 38; combinations[58][3] = 37; combinations[59][3] = 36; + combinations[56][4] = 27; combinations[57][4] = 26; combinations[58][4] = 25; combinations[59][4] = 24; + combinations[56][5] = 15; combinations[57][5] = 14; combinations[58][5] = 13; combinations[59][5] = 12; + + combinations[60][0] = 0; combinations[61][0] = 0; combinations[62][0] = 0; combinations[63][0] = 0; + combinations[60][1] = 0; combinations[61][1] = 0; combinations[62][1] = 0; combinations[63][1] = 0; + combinations[60][2] = 3; combinations[61][2] = 2; combinations[62][2] = 1; combinations[63][2] = 0; + combinations[60][3] = 23; combinations[61][3] = 22; combinations[62][3] = 21; combinations[63][3] = 20; + combinations[60][4] = 43; combinations[61][4] = 42; combinations[62][4] = 41; combinations[63][4] = 40; + combinations[60][5] = 63; combinations[61][5] = 62; combinations[62][5] = 61; combinations[63][5] = 60; + + // Diagonal, Y + + combinations[64][0] = 0; combinations[65][0] = 0; combinations[66][0] = 0; combinations[67][0] = 0; + combinations[64][1] = 0; combinations[65][1] = 0; combinations[66][1] = 0; combinations[67][1] = 0; + combinations[64][2] = 63; combinations[65][2] = 59; combinations[66][2] = 55; combinations[67][2] = 51; + combinations[64][3] = 46; combinations[65][3] = 42; combinations[66][3] = 38; combinations[67][3] = 34; + combinations[64][4] = 29; combinations[65][4] = 25; combinations[66][4] = 21; combinations[67][4] = 17; + combinations[64][5] = 12; combinations[65][5] = 8; combinations[66][5] = 4; combinations[67][5] = 0; + + combinations[68][0] = 0; combinations[69][0] = 0; combinations[70][0] = 0; combinations[71][0] = 0; + combinations[68][1] = 0; combinations[69][1] = 0; combinations[70][1] = 0; combinations[71][1] = 0; + combinations[68][2] = 15; combinations[69][2] = 11; combinations[70][2] = 7; combinations[71][2] = 3; + combinations[68][3] = 30; combinations[69][3] = 26; combinations[70][3] = 22; combinations[71][3] = 18; + combinations[68][4] = 45; combinations[69][4] = 41; combinations[70][4] = 37; combinations[71][4] = 33; + combinations[68][5] = 60; combinations[69][5] = 56; combinations[70][5] = 52; combinations[71][5] = 48; + + // Corner to Corner + + combinations[72][0] = 0; combinations[73][0] = 0; combinations[74][0] = 0; combinations[75][0] = 0; + combinations[72][1] = 0; combinations[73][1] = 0; combinations[74][1] = 0; combinations[75][1] = 0; + combinations[72][2] = 0; combinations[73][2] = 3; combinations[74][2] = 12; combinations[75][2] = 15; + combinations[72][3] = 21; combinations[73][3] = 22; combinations[74][3] = 25; combinations[75][3] = 26; + combinations[72][4] = 42; combinations[73][4] = 41; combinations[74][4] = 38; combinations[75][4] = 37; + combinations[72][5] = 63; combinations[73][5] = 60; combinations[74][5] = 51; combinations[75][5] = 48; + + // Initialize the combination flags to zero. + for (int i=0; i<76; i++) + combinations[i][6] = 0; + + // Set up the pos_to_comb array to point to every winning combination that a given + // position may have. + setup_pos_to_comb(); + + // Set up the best_picks array. + update_best_picks(); + } + + + /** + * Initialize the "outside four" array. + */ + public void init_outside_four() { + for (int i=0; i<18; i++) { + outside_four[i][0] = 0; + outside_four[i][1] = 0; + outside_four[i][2] = faces[i][ 2]; + outside_four[i][3] = faces[i][ 5]; + outside_four[i][4] = faces[i][14]; + outside_four[i][5] = faces[i][17]; + } + } + + + /** + * Initialize the "inside four" array. + */ + public void init_inside_four() { + for (int i=0; i<18; i++) { + inside_four[i][0] = 0; + inside_four[i][1] = 0; + inside_four[i][2] = faces[i][ 7]; + inside_four[i][3] = faces[i][ 8]; + inside_four[i][4] = faces[i][11]; + inside_four[i][5] = faces[i][12]; + } + } + + /** + * Initialize the "faces" array. + */ + public void init_faces () { + + faces[ 0][ 0] = 0; + faces[ 0][ 1] = 0; + faces[ 0][ 2] = 12; faces[ 0][ 6] = 13; faces[ 0][10] = 14; faces[ 0][14] = 15; + faces[ 0][ 3] = 8; faces[ 0][ 7] = 9; faces[ 0][11] = 10; faces[ 0][15] = 11; + faces[ 0][ 4] = 4; faces[ 0][ 8] = 5; faces[ 0][12] = 6; faces[ 0][16] = 7; + faces[ 0][ 5] = 0; faces[ 0][ 9] = 1; faces[ 0][13] = 2; faces[ 0][17] = 3; + + faces[ 1][ 0] = 0; + faces[ 1][ 1] = 0; + faces[ 1][ 2] = 28; faces[ 1][ 6] = 29; faces[ 1][10] = 30; faces[ 1][14] = 31; + faces[ 1][ 3] = 24; faces[ 1][ 7] = 25; faces[ 1][11] = 26; faces[ 1][15] = 27; + faces[ 1][ 4] = 20; faces[ 1][ 8] = 21; faces[ 1][12] = 22; faces[ 1][16] = 23; + faces[ 1][ 5] = 16; faces[ 1][ 9] = 17; faces[ 1][13] = 18; faces[ 1][17] = 19; + + faces[ 2][ 0] = 0; + faces[ 2][ 1] = 0; + faces[ 2][ 2] = 44; faces[ 2][ 6] = 45; faces[ 2][10] = 46; faces[ 2][14] = 47; + faces[ 2][ 3] = 40; faces[ 2][ 7] = 41; faces[ 2][11] = 42; faces[ 2][15] = 43; + faces[ 2][ 4] = 36; faces[ 2][ 8] = 37; faces[ 2][12] = 38; faces[ 2][16] = 39; + faces[ 2][ 5] = 32; faces[ 2][ 9] = 33; faces[ 2][13] = 34; faces[ 2][17] = 35; + + faces[ 3][ 0] = 0; + faces[ 3][ 1] = 0; + faces[ 3][ 2] = 60; faces[ 3][ 6] = 61; faces[ 3][10] = 62; faces[ 3][14] = 63; + faces[ 3][ 3] = 56; faces[ 3][ 7] = 57; faces[ 3][11] = 58; faces[ 3][15] = 59; + faces[ 3][ 4] = 52; faces[ 3][ 8] = 53; faces[ 3][12] = 54; faces[ 3][16] = 55; + faces[ 3][ 5] = 48; faces[ 3][ 9] = 49; faces[ 3][13] = 50; faces[ 3][17] = 51; + + faces[ 4][ 0] = 0; + faces[ 4][ 1] = 0; + faces[ 4][ 2] = 12; faces[ 4][ 6] = 28; faces[ 4][10] = 44; faces[ 4][14] = 60; + faces[ 4][ 3] = 8; faces[ 4][ 7] = 24; faces[ 4][11] = 40; faces[ 4][15] = 56; + faces[ 4][ 4] = 4; faces[ 4][ 8] = 20; faces[ 4][12] = 36; faces[ 4][16] = 52; + faces[ 4][ 5] = 0; faces[ 4][ 9] = 16; faces[ 4][13] = 32; faces[ 4][17] = 48; + + faces[ 5][ 0] = 0; + faces[ 5][ 1] = 0; + faces[ 5][ 2] = 13; faces[ 5][ 6] = 29; faces[ 5][10] = 45; faces[ 5][14] = 61; + faces[ 5][ 3] = 9; faces[ 5][ 7] = 25; faces[ 5][11] = 41; faces[ 5][15] = 57; + faces[ 5][ 4] = 5; faces[ 5][ 8] = 21; faces[ 5][12] = 37; faces[ 5][16] = 53; + faces[ 5][ 5] = 1; faces[ 5][ 9] = 17; faces[ 5][13] = 33; faces[ 5][17] = 49; + + faces[ 6][ 0] = 0; + faces[ 6][ 1] = 0; + faces[ 6][ 2] = 14; faces[ 6][ 6] = 30; faces[ 6][10] = 46; faces[ 6][14] = 62; + faces[ 6][ 3] = 10; faces[ 6][ 7] = 26; faces[ 6][11] = 42; faces[ 6][15] = 58; + faces[ 6][ 4] = 6; faces[ 6][ 8] = 22; faces[ 6][12] = 38; faces[ 6][16] = 54; + faces[ 6][ 5] = 2; faces[ 6][ 9] = 18; faces[ 6][13] = 34; faces[ 6][17] = 50; + + faces[ 7][ 0] = 0; + faces[ 7][ 1] = 0; + faces[ 7][ 2] = 15; faces[ 7][ 6] = 31; faces[ 7][10] = 47; faces[ 7][14] = 63; + faces[ 7][ 3] = 11; faces[ 7][ 7] = 27; faces[ 7][11] = 43; faces[ 7][15] = 59; + faces[ 7][ 4] = 7; faces[ 7][ 8] = 23; faces[ 7][12] = 39; faces[ 7][16] = 55; + faces[ 7][ 5] = 3; faces[ 7][ 9] = 19; faces[ 7][13] = 35; faces[ 7][17] = 51; + + faces[ 8][ 0] = 0; + faces[ 8][ 1] = 0; + faces[ 8][ 2] = 12; faces[ 8][ 6] = 28; faces[ 8][10] = 44; faces[ 8][14] = 60; + faces[ 8][ 3] = 13; faces[ 8][ 7] = 29; faces[ 8][11] = 45; faces[ 8][15] = 61; + faces[ 8][ 4] = 14; faces[ 8][ 8] = 30; faces[ 8][12] = 46; faces[ 8][16] = 62; + faces[ 8][ 5] = 15; faces[ 8][ 9] = 31; faces[ 8][13] = 47; faces[ 8][17] = 63; + + faces[ 9][ 0] = 0; + faces[ 9][ 1] = 0; + faces[ 9][ 2] = 8; faces[ 9][ 6] = 24; faces[ 9][10] = 40; faces[ 9][14] = 56; + faces[ 9][ 3] = 9; faces[ 9][ 7] = 25; faces[ 9][11] = 41; faces[ 9][15] = 57; + faces[ 9][ 4] = 10; faces[ 9][ 8] = 26; faces[ 9][12] = 42; faces[ 9][16] = 58; + faces[ 9][ 5] = 11; faces[ 9][ 9] = 27; faces[ 9][13] = 43; faces[ 9][17] = 59; + + faces[10][ 0] = 0; + faces[10][ 1] = 0; + faces[10][ 2] = 4; faces[10][ 6] = 20; faces[10][10] = 36; faces[10][14] = 52; + faces[10][ 3] = 5; faces[10][ 7] = 21; faces[10][11] = 37; faces[10][15] = 53; + faces[10][ 4] = 6; faces[10][ 8] = 22; faces[10][12] = 38; faces[10][16] = 54; + faces[10][ 5] = 7; faces[10][ 9] = 23; faces[10][13] = 39; faces[10][17] = 55; + + faces[11][ 0] = 0; + faces[11][ 1] = 0; + faces[11][ 2] = 0; faces[11][ 6] = 16; faces[11][10] = 32; faces[11][14] = 48; + faces[11][ 3] = 1; faces[11][ 7] = 17; faces[11][11] = 33; faces[11][15] = 49; + faces[11][ 4] = 2; faces[11][ 8] = 18; faces[11][12] = 34; faces[11][16] = 50; + faces[11][ 5] = 3; faces[11][ 9] = 19; faces[11][13] = 35; faces[11][17] = 51; + + faces[12][ 0] = 0; + faces[12][ 1] = 0; + faces[12][ 2] = 12; faces[12][ 6] = 13; faces[12][10] = 14; faces[12][14] = 15; + faces[12][ 3] = 24; faces[12][ 7] = 25; faces[12][11] = 26; faces[12][15] = 27; + faces[12][ 4] = 36; faces[12][ 8] = 37; faces[12][12] = 38; faces[12][16] = 39; + faces[12][ 5] = 48; faces[12][ 9] = 49; faces[12][13] = 50; faces[12][17] = 51; + + faces[13][ 0] = 0; + faces[13][ 1] = 0; + faces[13][ 2] = 0; faces[13][ 6] = 1; faces[13][10] = 2; faces[13][14] = 3; + faces[13][ 3] = 20; faces[13][ 7] = 21; faces[13][11] = 22; faces[13][15] = 23; + faces[13][ 4] = 40; faces[13][ 8] = 41; faces[13][12] = 42; faces[13][16] = 43; + faces[13][ 5] = 60; faces[13][ 9] = 61; faces[13][13] = 62; faces[13][17] = 63; + + faces[14][ 0] = 0; + faces[14][ 1] = 0; + faces[14][ 2] = 12; faces[14][ 6] = 28; faces[14][10] = 44; faces[14][14] = 60; + faces[14][ 3] = 9; faces[14][ 7] = 25; faces[14][11] = 41; faces[14][15] = 57; + faces[14][ 4] = 6; faces[14][ 8] = 22; faces[14][12] = 38; faces[14][16] = 54; + faces[14][ 5] = 3; faces[14][ 9] = 19; faces[14][13] = 35; faces[14][17] = 51; + + faces[15][ 0] = 0; + faces[15][ 1] = 0; + faces[15][ 2] = 15; faces[15][ 6] = 31; faces[15][10] = 47; faces[15][14] = 63; + faces[15][ 3] = 10; faces[15][ 7] = 26; faces[15][11] = 42; faces[15][15] = 58; + faces[15][ 4] = 5; faces[15][ 8] = 21; faces[15][12] = 37; faces[15][16] = 53; + faces[15][ 5] = 0; faces[15][ 9] = 16; faces[15][13] = 32; faces[15][17] = 48; + + faces[16][ 0] = 0; + faces[16][ 1] = 0; + faces[16][ 2] = 12; faces[16][ 6] = 29; faces[16][10] = 46; faces[16][14] = 63; + faces[16][ 3] = 8; faces[16][ 7] = 25; faces[16][11] = 42; faces[16][15] = 59; + faces[16][ 4] = 4; faces[16][ 8] = 21; faces[16][12] = 38; faces[16][16] = 55; + faces[16][ 5] = 0; faces[16][ 9] = 17; faces[16][13] = 34; faces[16][17] = 51; + + faces[17][ 0] = 0; + faces[17][ 1] = 0; + faces[17][ 2] = 15; faces[17][ 6] = 30; faces[17][10] = 45; faces[17][14] = 60; + faces[17][ 3] = 11; faces[17][ 7] = 26; faces[17][11] = 41; faces[17][15] = 56; + faces[17][ 4] = 7; faces[17][ 8] = 22; faces[17][12] = 37; faces[17][16] = 52; + faces[17][ 5] = 3; faces[17][ 9] = 18; faces[17][13] = 33; faces[17][17] = 48; + } + + /** + * Render the current face set in the 2D window. + */ + public void render2D(Graphics gc) { + + gc.setColor(background); + gc.fillRect(0, 0, width, height); + + int id; + int x, y; + + float begX; + float begY; + + for (int l=0; l<3; l++) { + begY = 28.0f + l*(5.f*23.3f); + for (int k=0; k<6; k++) { + begX = 11.65f + k*(5.f*11.65f); + int count = 0; + int face = l*6+k; + for (int i=0; i<4; i++) { + for (int j=0; j<4; j++) { + x = (int)begX + i*12; + y = (int)begY + j*12; + id = faces[face][count+2]; + if (occupied[id] == HUMAN) { + x -= 2; + y -= 2; + gc.setColor(red); + gc.fillRect(x, y, 5, 5); + } + else if (occupied[id] == MACHINE) { + x -= 2; + y -= 2; + gc.setColor(blue); + gc.fillRect(x, y, 5, 5); + } + else { + x -= 1; + y -= 1; + gc.setColor(gray); + gc.fillRect(x, y, 2, 2); + } + if (highlight[face]) { + gc.setColor(yellow); + positions.setHighlight(faces[face][count+2]); + } + count++; + } + } + if (highlight[face]) + gc.setColor(yellow); + else + gc.setColor(white); + if ((face+1)<10) + gc.drawString("Face "+(face+1), (int)begX-2, (int)begY+60); + else + gc.drawString("Face "+(face+1), (int)begX-4, (int)begY+60); + } + } + } + + /** + * Determine what position has been selected in the 2D window. + */ + public void checkSelection2D(int x, int y, int player) { + + int id; + int posX, posY; + + float begX; + float begY; + + for (int l=0; l<3; l++) { + begY = 28.0f + l*(5.f*23.3f); + for (int k=0; k<6; k++) { + begX = 11.65f + k*(5.f*11.65f); + int count = 0; + int face = l*6+k; + for (int i=0; i<4; i++) { + for (int j=0; j<4; j++) { + posX = (int)begX + i*12; + posY = (int)begY + j*12; + if (x > posX-4 && x < posX+4 && + y > posY-4 && y < posY+4) { + + id = faces[face][count+2]; + + if (occupied[id] == UNOCCUPIED) { + positions.set(id, player); + selection(id, player); + canvas.repaint(); + } + return; + } + count++; + } + } + if ((x > begX-4 && x < begX+40) && + (y > begY+45 && y < begY+60) ) { + + count = 0; + for (int i=0; i<4; i++) { + for (int j=0; j<4; j++) { + if (highlight[face]) + positions.clearHighlight(faces[face][count+2]); + count++; + } + } + if (highlight[face]) + highlight[face] = false; + else + highlight[face] = true; + canvas.repaint(); + } + } + } + + } + + + /** + * Record the player's move. + */ + public void selection(int pos, int player) { + + int num_combinations; + int comb; + + this.player = player; + + if (player == HUMAN) { + + // If position is already occupied, return. + if (occupied[pos] != 0) return; + + // Mark the position as HUMAN. + occupied[pos] = HUMAN; + + // Update the logic arrays. + this.player = update_logic_arrays(pos); + + // Have the computer determine its move. + choose_move(); + } + } + + + /** + * Determine the computer's move. + */ + public void choose_move () { + + if (player == MACHINE) { + + // Babe in the woods. + if (skill_level == 0) { + if (!block_winning_move()) { + if (!pick_7()) { + if (!check_outside_four()) { + pick_best_position(); + } + } + } + } + + // Walk and chew gum. + else if (skill_level == 1) { + if (!block_winning_move()) { + if (!block_intersecting_rows()) { + if (!block_inside_four()) { + if (!block_outside_four()) { + pick_best_position(); + } + } + } + } + } + + // Jeopordy contestant. + else if (skill_level == 2) { + if (!block_winning_move()) { + if (!block_intersecting_rows()) { + if (!block_inside_four()) { + if (!block_outside_four()) { + if (!pick_7()) { + pick_best_position(); + } + } + } + } + } + } + + // Rocket scientist. + else if (skill_level == 3) { + if (!block_winning_move()) { + if (!block_intersecting_rows()) { + if (!block_chair_move()) { + if (!check_face_three()) { + if (!block_central_four()) { + if (!block_inside_four()) { + if (!block_outside_four()) { + if (!take_inside_four()) { + if (!take_outside_four()) { + if (!pick_7()) { + if (!check_outside_four()) { + pick_best_position(); + } + } + } + } + } + } + } + } + } + } + } + } + + // Be afraid, be very afraid. + else if (skill_level == 4) { + if (!block_winning_move()) { + if (!block_intersecting_rows()) { + if (!block_chair_move()) { + if (!block_walk_move()) { + if (!block_central_four()) { + if (!block_inside_four()) { + if (!block_outside_four()) { + if (!check_face_three()) { + if (!check_intersecting_rows2()) { + if (!take_inside_four()) { + if (!take_outside_four()) { + if (!pick_7()) { + if (!check_outside_four()) { + pick_best_position(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + + /** + * Check for a winning move. + */ + public boolean block_winning_move() { + + // Loop through each combination and see if any player occupies + // three positions. If so, take the last remaining position. + int pos; + for (int i=0; i<76; i++) { + if (combinations[i][0] == 3) { + for (int j=2; j<6; j++) { + pos = combinations[i][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_winning_move: true"); + return true; + } + } + } + } + if (debug) System.out.println("check_winning_move: false"); + return false; + } + + + /** + * Block outside four + */ + public boolean block_outside_four() { + + int pos; + int index = 0; + int max = 0; + + // Block the opponent, if necessary. + for (int i=0; i<18; i++) { + if (outside_four[i][0] > 0 && + outside_four[i][1] == HUMAN) { + if(outside_four[i][0] > max) { + index = i; + max = outside_four[i][0]; + } + } + } + + if (max > 0) { + for (int j=2; j<6; j++) { + pos = outside_four[index][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_outside_four: true"); + return true; + } + } + } + + if (debug) System.out.println("block_outside_four: false"); + return false; + } + + + /** + * Block central four + */ + public boolean block_central_four() { + + int pos; + int index = 0; + int max = 0; + + // Block the opponent, if necessary. + for (int i=1; i<3; i++) { + if (inside_four[i][0] > 0 && + inside_four[i][1] == HUMAN) { + if(inside_four[i][0] > max) { + index = i; + max = inside_four[i][0]; + } + } + } + + if (max > 0) { + for (int j=2; j<6; j++) { + pos = inside_four[index][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_central_four: true"); + return true; + } + } + } + + if (debug) System.out.println("block_central_four: false"); + return false; + } + + /** + * Check each face for a forced win. + */ + public boolean check_face_three() { + + int pos; + int index = 0; + int human = 0; + int machine = 0; + + // Block the opponent from a forced win. + for (int i=0; i<18; i++) { + if (outside_four[i][0] == -1) { + human = 0; + machine = 0; + for (int j=2; j<6; j++) { + if (occupied[outside_four[i][j]] == MACHINE) + machine++; + else if (occupied[outside_four[i][j]] == HUMAN) + human++; + } + if (debug) System.out.println("machine = " + machine); + if (debug) System.out.println("human = " + human); + if (human == 3 && machine == 1) { + if (debug) System.out.println("human == 3 && machine == 1"); + for (int j=2; j<18; j++) { + pos = faces[i][j]; + if (occupied[pos] == 0) { + for (int k=0; k<76; k++) { + if (combinations[i][0] == 2 & + combinations[i][1] == HUMAN) { + for (int l=0; l<4; l++) { + if (combinations[i][l] == pos) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_face_three: true"); + return true; + } + } + } + } + } + } + } + } + } + + if (debug) System.out.println("check_face_three: false"); + return false; + } + + + + /** + * Block inside four + */ + public boolean block_inside_four() { + + int pos; + int index = 0; + int max = 0; + + // Block the opponent, if necessary. + for (int i=0; i<18; i++) { + if (inside_four[i][0] > 0 && + inside_four[i][1] == HUMAN) { + if(inside_four[i][0] > max) { + index = i; + max = inside_four[i][0]; + } + } + } + + if (max > 0) { + for (int j=2; j<6; j++) { + pos = inside_four[index][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_inside_four: true"); + return true; + } + } + } + + if (debug) System.out.println("block_inside_four: false"); + return false; + } + + + public boolean block_chair_move() { + + int pos; + + int ncorners = 0; // Number of corners owned by human + int corner = 0; // Corner owned by machine + + if (debug) System.out.println("inside block_chair_move"); + + // Loop through all of the faces. + for(int i=0; i<18; i++) { + + // Determine which corners the human owns. + if (occupied[faces[i][2]] == HUMAN) + ncorners++; + else if (occupied[faces[i][2]] == MACHINE) + corner = 2; + if (occupied[faces[i][5]] == HUMAN) + ncorners++; + else if (occupied[faces[i][5]] == MACHINE) + corner = 5; + if (occupied[faces[i][14]] == HUMAN) + ncorners++; + else if (occupied[faces[i][14]] == MACHINE) + corner = 14; + if (occupied[faces[i][17]] == HUMAN) + ncorners++; + else if (occupied[faces[i][17]] == MACHINE) + corner = 17; + + // If the human owns three corners, continue with the search. + if (ncorners == 3) { + if (corner == 2) { + if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][ 9]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][13]] == 0) { + pos = faces[i][8]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][ 9]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][12]] == 0 && occupied[faces[i][13]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 4]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][16]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + } + else if (corner == 5) { + if (occupied[faces[i][ 9]] == HUMAN && occupied[faces[i][ 6]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][10]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][13]] == HUMAN && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][10]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 4]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][ 7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + } + else if (corner == 14) { + if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][ 9]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][13]] == 0) { + pos = faces[i][7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][ 9]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][12]] == 0 && occupied[faces[i][13]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][3]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][12]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][12]] == 0 && occupied[faces[i][15]] == 0) { + pos = faces[i][7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 6]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 9]] == 0 && + occupied[faces[i][12]] == 0 && occupied[faces[i][13]] == 0) { + pos = faces[i][7]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + } + else if (corner == 17) { + if (occupied[faces[i][ 9]] == HUMAN && occupied[faces[i][ 6]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][10]] == 0 && occupied[faces[i][11]] == 0) { + pos = faces[i][8]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][13]] == HUMAN && occupied[faces[i][ 6]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][10]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 7]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][11]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) { + pos = faces[i][8]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][16]] == 0) { + pos = faces[i][8]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][ 3]] == 0 && + occupied[faces[i][ 4]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][15]] == 0) { + pos = faces[i][11]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + } + } + ncorners = 0; + corner = -1; + } + if (debug) System.out.println("block_chair_move: false"); + return false; + } + + public boolean block_walk_move() { + + int pos; + + if (debug) System.out.println("inside block_walk_move"); + + // Loop through all of the faces. + for(int i=0; i<18; i++) { + + // Look for a matching pattern. + if (occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][14]] == HUMAN && + occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][15]] == HUMAN && + occupied[faces[i][ 6]] == 0 && occupied[faces[i][10]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][11]] == 0) { + + if (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 9]] == 0) { + pos = faces[i][6]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][13]] == 0) { + pos = faces[i][10]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][14]] == HUMAN && occupied[faces[i][17]] == HUMAN && + occupied[faces[i][10]] == HUMAN && occupied[faces[i][13]] == HUMAN && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0 && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0) { + + if (occupied[faces[i][7]] == HUMAN && occupied[faces[i][3]] == 0) { + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if (occupied[faces[i][8]] == HUMAN && occupied[faces[i][4]] == 0) { + pos = faces[i][16]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][16]] == HUMAN && + occupied[faces[i][ 5]] == HUMAN && occupied[faces[i][17]] == HUMAN && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][ 9]] == 0 && occupied[faces[i][13]] == 0) { + + if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][10]] == 0) { + pos = faces[i][18]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if (occupied[faces[i][7]] == HUMAN && occupied[faces[i][6]] == 0) { + pos = faces[i][9]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 9]] == HUMAN && + occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][ 5]] == HUMAN && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0 && + occupied[faces[i][ 3]] == 0 && occupied[faces[i][ 4]] == 0) { + + if (occupied[faces[i][11]] == HUMAN && occupied[faces[i][15]] == 0) { + pos = faces[i][3]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if (occupied[faces[i][12]] == HUMAN && occupied[faces[i][16]] == 0) { + pos = faces[i][4]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][14]] == HUMAN && + occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][16]] == HUMAN && + occupied[faces[i][ 6]] == 0 && occupied[faces[i][10]] == 0 && + occupied[faces[i][ 8]] == 0 && occupied[faces[i][12]] == 0) { + + if ((occupied[faces[i][7]] == HUMAN && occupied[faces[i][9]] == 0) || + (occupied[faces[i][9]] == HUMAN && occupied[faces[i][7]] == 0) ) { + pos = faces[i][6]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if ((occupied[faces[i][11]] == HUMAN && occupied[faces[i][13]] == 0) || + (occupied[faces[i][13]] == HUMAN && occupied[faces[i][11]] == 0) ) { + pos = faces[i][10]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][14]] == HUMAN && occupied[faces[i][17]] == HUMAN && + occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 9]] == HUMAN && + occupied[faces[i][15]] == 0 && occupied[faces[i][16]] == 0 && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][ 8]] == 0) { + + if ((occupied[faces[i][11]] == HUMAN && occupied[faces[i][ 3]] == 0) || + (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][11]] == 0) ) { + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if ((occupied[faces[i][12]] == HUMAN && occupied[faces[i][ 4]] == 0) || + (occupied[faces[i][ 4]] == HUMAN && occupied[faces[i][12]] == 0) ) { + pos = faces[i][16]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][ 3]] == HUMAN && occupied[faces[i][15]] == HUMAN && + occupied[faces[i][ 5]] == HUMAN && occupied[faces[i][17]] == HUMAN && + occupied[faces[i][ 7]] == 0 && occupied[faces[i][11]] == 0 && + occupied[faces[i][ 9]] == 0 && occupied[faces[i][13]] == 0) { + + if ((occupied[faces[i][ 6]] == HUMAN && occupied[faces[i][ 8]] == 0) || + (occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][ 6]] == 0) ) { + pos = faces[i][9]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if ((occupied[faces[i][10]] == HUMAN && occupied[faces[i][12]] == 0) || + (occupied[faces[i][12]] == HUMAN && occupied[faces[i][10]] == 0) ) { + pos = faces[i][13]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a matching pattern. + if (occupied[faces[i][10]] == HUMAN && occupied[faces[i][13]] == HUMAN && + occupied[faces[i][ 2]] == HUMAN && occupied[faces[i][ 5]] == HUMAN && + occupied[faces[i][11]] == 0 && occupied[faces[i][12]] == 0 && + occupied[faces[i][ 3]] == 0 && occupied[faces[i][ 4]] == 0) { + + if ((occupied[faces[i][ 7]] == HUMAN && occupied[faces[i][15]] == 0) || + (occupied[faces[i][15]] == HUMAN && occupied[faces[i][ 7]] == 0) ) { + pos = faces[i][3]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + else if ((occupied[faces[i][ 8]] == HUMAN && occupied[faces[i][16]] == 0) || + (occupied[faces[i][16]] == HUMAN && occupied[faces[i][ 8]] == 0) ) { + pos = faces[i][4]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + } + + if (debug) System.out.println("block_walk_move: false"); + return false; + } + + public boolean check_chair_move() { + + int pos; + + // If the "block chair flag" is set, all we need to do is + // block the winning path... + if (block_chair_flag) { + pos = faces[block_chair_face][block_chair_next_move]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: march"); + return true; + } + + int ncorners = 0; // Number of corners owned by human + int corner = 0; // Corner owned by machine + + // Loop through all of the faces. + for(int i=0; i<18; i++) { + + // Determine which corners the human owns. + if (faces[i][ 2] == HUMAN) + ncorners++; + else + corner = 2; + if (faces[i][ 5] == HUMAN) + ncorners++; + else + corner = 5; + if (faces[i][14] == HUMAN) + ncorners++; + else + corner = 14; + if (faces[i][17] == HUMAN) + ncorners++; + else + corner = 17; + + // If the human owns three corners, continue with the search. + if (ncorners == 3) { + if (corner == 2) { + if (faces[i][ 3] == HUMAN && faces[i][ 7] == 0 && + faces[i][ 8] == 0 && faces[i][11] == 0 && + faces[i][15] == 0 && faces[i][16] == 0) { + block_chair_flag = true; + block_chair_next_move = 11; + block_chair_face = i; + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + if (faces[i][ 4] == HUMAN && faces[i][ 8] == 0 && + faces[i][11] == 0 && faces[i][12] == 0 && + faces[i][15] == 0 && faces[i][16] == 0) { + block_chair_flag = true; + block_chair_next_move = 16; + block_chair_face = i; + pos = faces[i][8]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_chair_move: found"); + return true; + } + } + else if (corner == 5) { + block_chair_flag = true; + block_chair_next_move = 11; + block_chair_face = i; + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_face_three: true"); + return true; + } + else if (corner == 14) { + block_chair_flag = true; + block_chair_next_move = 11; + block_chair_face = i; + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_face_three: true"); + return true; + } + else if (corner == 17) { + block_chair_flag = true; + block_chair_next_move = 11; + block_chair_face = i; + pos = faces[i][15]; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_face_three: true"); + return true; + } + } + } + return false; + } + + /** + * Take inside four + */ + public boolean take_inside_four() { + + int pos = 0; + boolean found = false; + + if (occupied[21] == 0) { + found = true; + pos = 21; + } + else if (occupied[22] == 0) { + found = true; + pos = 22; + } + else if (occupied[25] == 0) { + found = true; + pos = 25; + } + else if (occupied[26] == 0) { + found = true; + pos = 26; + } + else if (occupied[37] == 0) { + found = true; + pos = 37; + } + else if (occupied[38] == 0) { + found = true; + pos = 38; + } + else if (occupied[41] == 0) { + found = true; + pos = 41; + } + else if (occupied[42] == 0) { + found = true; + pos = 42; + } + + if (found) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("take_inside_four: true"); + return true; + } + + if (debug) System.out.println("take_inside_four: false"); + return false; + } + + + /** + * Check occupancy of outside four. + */ + public boolean check_outside_four() { + + int pos = 0; + + // Finish off the four corner combination. + if (outside_four_flag) { + if (occupied[faces[face_index][7]] == 0) { + pos = faces[face_index][7]; + } + else if (occupied[faces[face_index][6]] == 0) { + pos = faces[face_index][6]; + } + + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + return true; + } + } + + // Look for a four corner combination. + for (int i=0; i<18; i++) { + if (outside_four[i][0] == 4 && + outside_four[i][1] == MACHINE) { + if (faces[i][0] > 0 && + faces[i][1] == MACHINE) { + if (occupied[faces[i][8]] == 0) { + pos = faces[i][8]; + outside_four_flag = true; + face_index = i; + } + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_outside_four: true"); + return true; + } + } + } + } + + // Take the corners, if available. + for (int i=0; i<18; i++) { + if (outside_four[i][0] > 0 && + outside_four[i][1] == MACHINE) { + if (faces[i][0] > 0 && + faces[i][1] == MACHINE) { + for (int j=2; j<6; j++) { + pos = outside_four[i][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_outside_four: true"); + return true; + } + } + } + } + } + + // Look for an "outside four" combination in a face in which the + // opponent holds no positions. + for (int i=0; i<18; i++) { + if (outside_four[i][0] == 0 || (outside_four[i][0] > 0 && + outside_four[i][1] == MACHINE)) { + + if (outside_four[i][1] == MACHINE) + outside_four_flag = true; + for (int j=2; j<6; j++) { + pos = outside_four[i][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_outside_four: true"); + return true; + } + } + } + } + + if (debug) System.out.println("check_outside_four: false"); + return false; + } + + + /** + * Take outside four + */ + public boolean take_outside_four() { + + int pos = 0; + boolean found = false; + + if (occupied[0] == 0) { + found = true; + pos = 0; + } + else if (occupied[3] == 0) { + found = true; + pos = 3; + } + else if (occupied[12] == 0) { + found = true; + pos = 12; + } + else if (occupied[15] == 0) { + found = true; + pos = 15; + } + else if (occupied[48] == 0) { + found = true; + pos = 48; + } + else if (occupied[51] == 0) { + found = true; + pos = 51; + } + else if (occupied[60] == 0) { + found = true; + pos = 60; + } + else if (occupied[63] == 0) { + found = true; + pos = 63; + } + + if (found) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("take_outside_four: true"); + return true; + } + + if (debug) System.out.println("take_outside_four: false"); + return false; + } + + + /** + * Check for a forced win by intersecting rows. Block + * if necessary. + */ + public boolean block_intersecting_rows() { + + int pos; + + // Loop through each row and check for rows that have two + // positions occupied by the human and two positions which are empty. + // Make sure that none of the empty positions in this row intersect + // with another row that also contains two positions held by the human. + // If so, block the row by taking the position at the intersection + // of these two row. + + // Loop through each row. + for (int i=0; i<76; i++) { + + // Look for a row that has two positions held by the human. + if (combinations[i][0] == 2 && combinations[i][1] == HUMAN) { + + if (debug) + System.out.println(" row " + i + "has 2 positions occupied by the human"); + + // Mark this row with a flag. + combinations[i][6] = 1; + + // Check each position in the row. + for (int j=2; j<6; j++) { + + // Look for the empty positions in the row. + pos = combinations[i][j]; + if (occupied[pos] == 0) { + + // Loop through the rows again. + for (int k=0; k<76; k++) { + + if (debug) System.out.println(" row " + k); + + // Look for another row that has two positions held + // by the human (and which is unmarked.) modified + if (combinations[k][0] == 2 && + combinations[k][1] == HUMAN && + combinations[k][6] == 0) { + + if (debug) + System.out.println("found an intersecting row: row " + k); + + // Check the positions in this row and see if + // any match the position we're looking for. If + // we find a match, grab the position and return. + for (int l=2; l<6; l++) { + if (pos == combinations[k][l]) { + combinations[i][6] = 0; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("block_intersecting_rows: true"); + return true; + } + } + } + } + } + } + + // Unmark the combination before moving on. + combinations[i][6] = 0; + } + + } + if (debug) System.out.println("block_intersecting_rows: false"); + return false; + } + + /** + * Check for a forced win by intersecting rows. Block + * if necessary. + */ + public boolean check_intersecting_rows2() { + + int pos; + + // Loop through each row and check for rows that have two + // positions occupied by the human and two positions which are empty. + // Make sure that none of the empty positions in this row intersect + // with another row that also contains two positions held by the human. + // If so, block the row by taking the position at the intersection + // of these two row. + + // Loop through each row. + for (int i=0; i<76; i++) { + + // Look for a row that has two positions held by the human. + if (combinations[i][0] == 2 && combinations[i][1] == HUMAN) { + + if (debug) { + System.out.println(" row " + i + "has 2 positions occupied by the human"); + } + + // Mark this row with a flag. + combinations[i][6] = 1; + + // Check each position in the row. + for (int j=2; j<6; j++) { + + // Look for the empty positions in the row. + pos = combinations[i][j]; + if (occupied[pos] == 0) { + + // Loop through the rows again. + for (int k=0; k<76; k++) { + + if (debug) System.out.println(" row " + k); + + // Look for another row that has two positions held + // by the human (and which is unmarked.) modified + if (combinations[k][0] == 1 && + combinations[k][1] == HUMAN && + combinations[k][6] == 0) { + + if (debug) + System.out.println("found an intersecting row: row " + k); + + // Check the positions in this row and see if + // any match the position we're looking for. If + // we find a match, grab the position and return. + for (int l=2; l<6; l++) { + if (pos == combinations[k][l]) { + combinations[i][6] = 0; + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_intersecting_rows: true"); + return true; + } + } + } + } + } + } + + // Unmark the combination before moving on. + combinations[i][6] = 0; + } + + } + if (debug) System.out.println("check_intersecting_rows: false"); + return false; + } + + + /** + * Check for a forced win by intersecting rows. Block + * if necessary. + */ + public boolean check_for_two() { + + int pos; + + // Loop through the rows. + for (int i=0; i<76; i++) { + + // Look for a row that has two positions held + // by the human (and which is unmarked.) + if (combinations[i][0] == 2 && + combinations[i][1] == HUMAN && + combinations[i][6] == 0) { + + // Take the first available spot. + for (int j=2; j<6; j++) { + pos = combinations[i][j]; + if (occupied[pos] == 0) { + occupied[pos] = MACHINE; + positions.set(pos, MACHINE); + player = update_logic_arrays(pos); + if (debug) System.out.println("check_for_two: true"); + return true; + } + } + + } + } + if (debug) System.out.println("check_for_two: false"); + return false; + } + + public void undo_move() { + + // Return if no moves are recorded + if (nmoves == 0) return; + + // Set the undo flag + undoFlag = true; + + // Undo the last two moves + positions.clear(moves[--nmoves]); + positions.clear(moves[--nmoves]); + + // Undo the winner flag in the positions object + positions.noWinner(); + + // Repaint the 2D canvas. + canvas.repaint(); + + // Reset the inside/outside flags + inside_four_flag = false; + outside_four_flag = false; + block_chair_flag = false; + + // Reset the board + for (int i=0; i<64; i++) { + occupied[i] = 0; + } + + // Reset the inside/outside arrays + for (int i=0; i<18; i++) { + inside_four[i][0] = 0; + inside_four[i][1] = 0; + outside_four[i][0] = 0; + outside_four[i][1] = 0; + } + + // Reset the faces array + for (int i=0; i<18; i++) { + faces[i][0] = 0; + faces[i][1] = 0; + } + + // Reset the combinations array + for (int i=0; i<76; i++) { + combinations[i][0] = 0; + combinations[i][1] = 0; + } + + if (nmoves == 0) { + undoFlag = false; + player = HUMAN; + return; + } + + // Update the logic arrays + int pos; + player = HUMAN; + for (int i=0; i<nmoves; i++) { + pos = moves[i]; + occupied[pos] = player; + player = update_logic_arrays(pos); + } + + // Reset the "best picks" array + update_best_picks(); + + // Reset the player and undo flag + player = HUMAN; + undoFlag = false; + } + + /** + * Update the logic arrays that keep track of positions and status. + * If we have a winner, stop the game. + */ + public int update_logic_arrays(int pos) { + + // Record the move. + if (!undoFlag) { + moves[nmoves++] = pos; + } + + // Get the number of combinations that this position has. + int num_combinations = pos_to_comb[pos][0]; + + // Go through each combination associated with this position + // and update the status. If we have a winner, stop the game. + int comb; + for (int j=0; j<num_combinations; j++) { + comb = pos_to_comb[pos][j+1]; + if (combinations[comb][1] != player && + combinations[comb][1] != 0) { + combinations[comb][0] = -1; + } + else { + combinations[comb][0]++; + if (combinations[comb][0] == 4) { + end_time = System.currentTimeMillis(); + time = (end_time - beg_time)/1000; + panel.winner(player, skill_level, nmoves, time); + panel.repaint(); + canvas.repaint(); + positions.winner(); + return END; + } + else { + combinations[comb][1] = player; + } + } + } + + // Update the best_picks array. + update_best_picks(); + + // Update the inside_four array. + for (int i=0; i<18; i++) { + for (int j=2; j<6; j++) { + if (pos == inside_four[i][j]) { + if (inside_four[i][0] == 0) { + inside_four[i][0] = 1; + inside_four[i][1] = player; + } + else if (inside_four[i][1] == player) { + inside_four[i][0]++; + inside_four[i][1] = player; + } + else { + inside_four[i][0] = -1; + } + } + } + } + + // Update the outside_four array. + for (int i=0; i<18; i++) { + for (int j=2; j<6; j++) { + if (pos == outside_four[i][j]) { + if (outside_four[i][0] == 0) { + outside_four[i][0] = 1; + outside_four[i][1] = player; + } + else if (outside_four[i][1] == player) { + outside_four[i][0]++; + outside_four[i][1] = player; + } + else { + outside_four[i][0] = -1; + } + } + } + } + + // Update the faces array. + for (int i=0; i<18; i++) { + for (int j=2; j<18; j++) { + if (pos == faces[i][j]) { + if (faces[i][0] == 0) { + faces[i][0] = 1; + faces[i][1] = player; + } + else if (faces[i][1] == player) { + faces[i][0]++; + } + else { + faces[i][0] = -1; + } + } + } + + } + + // Switch players. + if (player == HUMAN) + return MACHINE; + else + return HUMAN; + } + + + /** + * Start a new game. + */ + public void newGame() { + + // Initialize the inside/outside flags. + inside_four_flag = false; + outside_four_flag = false; + block_chair_flag = false; + + // Initialize the inside/outside arrays. + for (int i=0; i<18; i++) { + inside_four[i][0] = 0; + inside_four[i][1] = 0; + outside_four[i][0] = 0; + outside_four[i][1] = 0; + } + + // Initialize the faces array. + for (int i=0; i<18; i++) { + faces[i][0] = 0; + faces[i][1] = 0; + } + + // Initialize the board. + for (int i=0; i<64; i++) { + occupied[i] = 0; + } + for (int i=0; i<76; i++) { + combinations[i][0] = 0; + combinations[i][1] = 0; + } + + // Reset the best_picks array. + update_best_picks(); + + // Set the player with the first move. + player = HUMAN; + + // Initialize the number of moves. + nmoves = 0; + + // Reset the playing positions. + positions.newGame(); + } + + + /** + * Set the skill level. + */ + public void set_skill_level(int level) { + skill_level = level; + } + + + /** + * Set up the pos_to_comb array. + */ + public void setup_pos_to_comb() { + + // Set up the pos_to_comb array to point to every winning + // combination a given position may have. + int count; + for (int i=0; i<64; i++) { + count = 1; + pos_to_comb[i][0] = 0; + for (int j=0; j<76; j++) { + for (int k=2; k<6; k++) { + if (combinations[j][k] == i) { + pos_to_comb[i][0]++; + pos_to_comb[i][count++] = j; + } + } + } + } + + if (debug) { + for (int i=0; i<64; i++) { + System.out.println(""); + for (int j=0; j<8; j++) { + System.out.println("pos_to_comb[" + i + "][" + j + "] = " + pos_to_comb[i][j]); + } + } + } + + } + + + /** + * Update the best_picks array. + */ + public void update_best_picks() { + + // Re-calculate the best_picks array to point to every (current) winning + // combination a given position may have. + int count; + for (int i=0; i<64; i++) { + + count = 1; + best_picks[i][0] = 0; + if (occupied[i] == 0) { + for (int j=0; j<76; j++) { + + if (combinations[j][0] == 0 || + combinations[j][1] == MACHINE) { + + for (int k=2; k<6; k++) { + if (combinations[j][k] == i) { + best_picks[i][0]++; + best_picks[i][count++] = j; + } + } + } + } + } + } + + if (debug) { + for (int i=0; i<64; i++) { + System.out.println(""); + for (int j=0; j<8; j++) { + System.out.println("best_picks[" + i + "][" + j + "] = " + best_picks[i][j]); + } + } + } + } + + + /** + * Pick the computer's best possible move based on the number + * of combinations per position. Choose the position with the + * most combinations. + */ + public void pick_best_position() { + + int pos = 0; + int max_num = 0; + for (int i=0; i<64; i++) { + if (best_picks[i][0] > max_num && + occupied[i] == 0) { + pos = i; + max_num = best_picks[i][0]; + } + } + + // Mark the position as MACHINE. + occupied[pos] = MACHINE; + + positions.set(pos, MACHINE); + + // Udate the logic arrays and reset the player. + player = update_logic_arrays(pos); + } + + + public boolean pick_7() { + + for (int i=0; i<64; i++) { + if (best_picks[i][0] == 7) { + occupied[i] = MACHINE; + positions.set(i, MACHINE); + player = update_logic_arrays(i); + return true; + } + } + return false; + + } + + public void change_face() { + current_face = ++current_face%18; + } + + public void label() { + label_flag ^= true; + } + + public boolean unoccupied(int pos) { + if (occupied[pos] == UNOCCUPIED) + return true; + else + return false; + } +} diff --git a/src/FourByFour/Canvas2D.java b/src/FourByFour/Canvas2D.java new file mode 100644 index 0000000..53c21ad --- /dev/null +++ b/src/FourByFour/Canvas2D.java @@ -0,0 +1,92 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import java.awt.*; +import java.awt.event.*; +import java.awt.image.*; + +/** + * Class: Canvas2D + * + * Description: Used to respond to mouse events in the 2D window. + * + * Version: 1.0 + * + */ +class Canvas2D extends Canvas implements MouseListener { + + Image backbuffer; // Backbuffer image + Graphics gc; // Graphics context of backbuffer + Board board; // Game board + + Canvas2D(Board board) { + this.board = board; + } + + public void setBuffer(Image backbuffer) { + this.backbuffer = backbuffer; + gc = backbuffer.getGraphics(); + } + + public void update(Graphics g) { + paint(g); + } + + public void paint(Graphics g) { + if (board != null) { + board.render2D(gc); + g.drawImage(backbuffer, 0, 0, this); + } + } + + public void mousePressed(MouseEvent e) { + board.checkSelection2D(e.getX(), e.getY(), 1); + repaint(); + } + + public void mouseClicked(MouseEvent e) {} + public void mouseReleased(MouseEvent e) {} + public void mouseEntered(MouseEvent e) {} + public void mouseExited(MouseEvent e) {} +} diff --git a/src/FourByFour/Cube.java b/src/FourByFour/Cube.java new file mode 100644 index 0000000..f24f95f --- /dev/null +++ b/src/FourByFour/Cube.java @@ -0,0 +1,131 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import java.applet.Applet; +import java.awt.event.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +public class Cube extends Object { + + private Shape3D shape3D; + + private static final float[] verts = { + // Front Face + 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, + // Back Face + -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, + 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, + // Right Face + 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, + // Left Face + -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, + // Top Face + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, + // Bottom Face + -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, + 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, + }; + + private static final float[] normals = { + // Front Face + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + // Back Face + 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, + // Right Face + 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + // Left Face + -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + // Top Face + 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + // Bottom Face + 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, + 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, + }; + + public Cube(Appearance appearance) { + + QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES | + QuadArray.NORMALS | + QuadArray.TEXTURE_COORDINATE_2); + quadArray.setCoordinates(0, verts); + quadArray.setNormals(0, normals); + + shape3D = new Shape3D(quadArray, appearance); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + } + + public Cube(Appearance appearance, float size) { + + QuadArray quadArray = new QuadArray(24, QuadArray.COORDINATES | + QuadArray.NORMALS); + for (int i=0; i<72; i++) + verts[i] *= size; + + quadArray.setCoordinates(0, verts); + quadArray.setNormals(0, normals); + + shape3D = new Shape3D(quadArray, appearance); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_READ); + shape3D.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_READ); + shape3D.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE); + } + + public Shape3D getChild() { + return shape3D; + } +} diff --git a/src/FourByFour/Cylinder.java b/src/FourByFour/Cylinder.java new file mode 100644 index 0000000..db8dbfb --- /dev/null +++ b/src/FourByFour/Cylinder.java @@ -0,0 +1,114 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import javax.media.j3d.*; +import javax.vecmath.*; + +public class Cylinder { + + float verts[]; + float normals[]; + QuadArray quad = null; + float div = 3.0f; + Shape3D shape; + + public Cylinder(float x, float z, float radius, float length, int quality, Appearance a) { + + if (quality < 3) quality = 3; + + div = (float) quality; + + verts = new float[quality*12]; + normals = new float[quality*12]; + + double inc = 2.0*Math.PI/(double)div; + for (int i=0; i< quality; i++){ + float z1 = radius * (float)Math.sin((double)i*inc) + z; + float x1 = radius * (float)Math.cos((double)i*inc) + x; + float z2 = radius * (float)Math.sin((double)(i+1)*inc) + z; + float x2 = radius * (float)Math.cos((double)(i+1)*inc) + x; + + verts[12*i] = x1; + verts[12*i+1] = -length/2.f; + verts[12*i+2] = z1; + verts[12*i+3] = x1; + verts[12*i+4] = length/2.f; + verts[12*i+5] = z1; + verts[12*i+6] = x2; + verts[12*i+7] = length/2.f; + verts[12*i+8] = z2; + verts[12*i+9] = x2; + verts[12*i+10] = -length/2.f; + verts[12*i+11] = z2; + + float nz1 = (float)Math.sin((double)i*inc); + float nx1 = (float)Math.cos((double)i*inc); + float nz2 = (float)Math.sin((double)(i+1)*inc); + float nx2 = (float)Math.cos((double)(i+1)*inc); + + normals[12*i] = nx1; + normals[12*i+1] = 0.0f; + normals[12*i+2] = nz1; + normals[12*i+3] = nx1; + normals[12*i+4] = 0.0f; + normals[12*i+5] = nz1; + normals[12*i+6] = nx2; + normals[12*i+7] = 0.0f; + normals[12*i+8] = nz2; + normals[12*i+9] = nx2; + normals[12*i+10] = 0.0f; + normals[12*i+11] = nz2; + } + + quad = new QuadArray(quality*4, QuadArray.COORDINATES | + QuadArray.NORMALS ); + quad.setCoordinates(0, verts); + quad.setNormals(0, normals); + shape = new Shape3D(quad, a); + } + + Shape3D getShape(){ + return shape; + } +} diff --git a/src/FourByFour/FourByFour.html b/src/FourByFour/FourByFour.html new file mode 100644 index 0000000..8adb168 --- /dev/null +++ b/src/FourByFour/FourByFour.html @@ -0,0 +1,15 @@ +<HTML> +<HEAD> +<TITLE>Drag the mouse in the window</TITLE> +</HEAD> +<BODY BGCOLOR="#0C0C33"> +<applet align=middle code="FourByFour.class" width=716 height=410> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see "FourByFour" instead of this paragraph. +<hr> +</blockquote> +</applet> +</BODY> +</HTML> diff --git a/src/FourByFour/FourByFour.java b/src/FourByFour/FourByFour.java new file mode 100644 index 0000000..9820214 --- /dev/null +++ b/src/FourByFour/FourByFour.java @@ -0,0 +1,884 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import java.applet.Applet; +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import java.net.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import com.sun.j3d.utils.universe.SimpleUniverse; +import com.sun.j3d.utils.applet.MainFrame; + +/** + * Class FourByFour + * + * Description: High level class for the game FourByFour + * + * Version: 1.2 + * + */ +public class FourByFour extends Applet implements ActionListener { + + String host; // Host from which this applet came from + int port; // Port number for writing high scores + Image backbuffer2D; // Backbuffer image used for 2D double buffering + int width, height; // Size of the graphics window in pixels + int score; // Final game score + int level_weight; // Weighting factor for skill level + int move_weight; // Weighting factor for number of moves to win + int time_weight; // Weighting factor for amount of time it took to win + int skill_level; // Skill level, 0 - 4 + Canvas2D canvas2D; // 2D rendering canvas + Canvas3D canvas3D; // 3D rendering canvas + Board board; // Game board object + Panel b_container; // Container to hold the buttons + Panel c_container; // Container to hold the canvas + Panel l_container; // Container to hold the labels + Panel skill_panel; // Panel to hold skill levels + Panel instruct_panel; // Panel to hold instructions + Panel winner_panel; // Panel to hold winner announcement + Panel high_panel; // Panel to hold high scores + Button instruct_button; // Instructions button + Button new_button; // New Game button + Button skill_button; // Skill Level button + Button high_button; // High Scores button + Button undo_button; // Undo Move button + Label skill_label; // Label on skill panel + Label winner_label; // Label on winner panel + Label winner_score_label; // Score label on winner panel + Label winner_name_label; // Name label on winner panel + Label winner_top_label; // Top 20 label on winner panel + Label high_label; // High score label + Label high_places[]; // Labels to hold places + Label high_names[]; // Labels to hold names + Label high_scores[]; // Labels to hold scores + TextArea instruct_text; // TextArea object that holds instructions + TextArea high_text; // TextArea object that holds top 20 scores + TextField winner_name; // TextField object that holds winner's name + Button instruct_return_button; // Return button for instruction panel + Button skill_return_button; // Return button for skill level panel + Button winner_return_button; // Return button for winner panel + Button high_return_button; // Return button for high scores panel + CheckboxGroup group; // CheckboxGroup object for skill level panel + InputStream inStream; // Input stream for reading instructions and high scores + OutputStream outStream; // Output stream for writing high scores + static boolean appletFlag = true; // Applet flag + boolean winner_flag = false; // Winner flag + byte text[]; // Temporary storage area for reading instructions file + byte outText[]; // Temporary storage area for writing high scores file + String textString; // Storage area for instructions + String scoresString; // String used for writing high scores file + int places[]; // Storage area for high score places + int scores[]; // Storage area for high score scores + String names[]; // Storage area for high score names + Positions positions; // Positions object, used to render player positions + + private SimpleUniverse universe = null; + + /** + * Initialization + */ + public void init() { + + // Set the port number. + port = 4111; + + // Set the graphics window size. + width = 350; + height = 350; + + // Set the weighting factors used for scoring. + level_weight = 1311; + move_weight = 111; + time_weight = 1000; + + // Create the "base" color for the AWT components. + setBackground(new Color(200, 200, 200)); + + // Read the instructions file. + if (appletFlag) { + + // Get the host from which this applet came. + host = getCodeBase().getHost(); + + try { + inStream = new BufferedInputStream + (new URL(getCodeBase(), "instructions.txt").openStream(), 8192); + text = new byte[5000]; + int character = inStream.read(); + int count = 0; + while (character != -1) { + text[count++] = (byte) character; + character = inStream.read(); + } + textString = new String(text); + inStream.close(); + } + catch(Exception e) { + System.out.println("Error: " + e.toString()); + } + } + else { + + try { + inStream = new BufferedInputStream + (new FileInputStream("instructions.txt")); + text = new byte[5000]; + int character = inStream.read(); + int count = 0; + while (character != -1) { + text[count++] = (byte) character; + character = inStream.read(); + } + textString = new String(text); + inStream.close(); + } + catch(Exception e) { + System.out.println("Error: " + e.toString()); + } + } + + // Read the high-scores file. + places = new int[20]; + scores = new int[20]; + names = new String[20]; + if (appletFlag) { + try { + inStream = new BufferedInputStream + (new URL(getCodeBase(), "scores.txt").openStream(), 8192); + Reader read = new BufferedReader(new InputStreamReader(inStream)); + StreamTokenizer st = new StreamTokenizer(read); + st.whitespaceChars(32,44); + st.eolIsSignificant(false); + + int count = 0; + int token = st.nextToken(); + boolean scoreFlag = true; + String string; + while (count<20) { + places[count] = (int) st.nval; + string = new String(""); + token = st.nextToken(); + while (token == StreamTokenizer.TT_WORD) { + string += st.sval; + string += " "; + token = st.nextToken(); + } + names[count] = string; + scores[count] = (int) st.nval; + token = st.nextToken(); + count++; + } + inStream.close(); + } + catch(Exception e) { + System.out.println("Error: " + e.toString()); + } + } + else { + try { + inStream = new BufferedInputStream + (new FileInputStream("scores.txt")); + Reader read = new BufferedReader(new InputStreamReader(inStream)); + StreamTokenizer st = new StreamTokenizer(read); + st.whitespaceChars(32,44); + st.eolIsSignificant(false); + + int count = 0; + int token = st.nextToken(); + boolean scoreFlag = true; + String string; + while (count<20) { + places[count] = (int) st.nval; + string = new String(""); + token = st.nextToken(); + while (token == StreamTokenizer.TT_WORD) { + string += st.sval; + string += " "; + token = st.nextToken(); + } + names[count] = string; + scores[count] = (int) st.nval; + token = st.nextToken(); + count++; + } + inStream.close(); + } + catch(Exception e) { + System.out.println("Error: " + e.toString()); + } + } + + // The positions object sets up the switch nodes which + // control the rendering of the player's positions. + positions = new Positions(); + + // Create the game board object which is responsible + // for keeping track of the moves on the game board + // and determining what move the computer should make. + board = new Board(this, positions, width, height); + positions.setBoard(board); + + // Create a 2D graphics canvas. + canvas2D = new Canvas2D(board); + canvas2D.setSize(width, height); + canvas2D.setLocation(width+10, 5); + canvas2D.addMouseListener(canvas2D); + board.setCanvas(canvas2D); + + // Create the 2D backbuffer + backbuffer2D = createImage(width, height); + canvas2D.setBuffer(backbuffer2D); + + // Create a 3D graphics canvas. + canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); + canvas3D.setSize(width, height); + canvas3D.setLocation(5, 5); + + // Create the scene branchgroup. + BranchGroup scene3D = createScene3D(); + + // Create a universe with the Java3D universe utility. + universe = new SimpleUniverse(canvas3D); + universe.addBranchGraph(scene3D); + + // Use parallel projection. + View view = universe.getViewer().getView(); + view.setProjectionPolicy(View.PARALLEL_PROJECTION); + + // Set the universe Transform3D object. + TransformGroup tg = + universe.getViewingPlatform().getViewPlatformTransform(); + Transform3D transform = new Transform3D(); + transform.set(65.f, new Vector3f(0.0f, 0.0f, 400.0f)); + tg.setTransform(transform); + + // Create the canvas container. + c_container = new Panel(); + c_container.setSize(720, 360); + c_container.setLocation(0, 0); + c_container.setVisible(true); + c_container.setLayout(null); + add(c_container); + + // Add the 2D and 3D canvases to the container. + c_container.add(canvas2D); + c_container.add(canvas3D); + + // Turn off the layout manager, widgets will be sized + // and positioned explicitly. + setLayout(null); + + // Create the button container. + b_container = new Panel(); + b_container.setSize(720, 70); + b_container.setLocation(0, 360); + b_container.setVisible(true); + b_container.setLayout(null); + + // Create the buttons. + instruct_button = new Button("Instructions"); + instruct_button.setSize(135, 25); + instruct_button.setLocation(10, 10); + instruct_button.setVisible(true); + instruct_button.addActionListener(this); + + new_button = new Button("New Game"); + new_button.setSize(135, 25); + new_button.setLocation(150, 10); + new_button.setVisible(true); + new_button.addActionListener(this); + + undo_button = new Button("Undo Move"); + undo_button.setSize(135, 25); + undo_button.setLocation(290, 10); + undo_button.setVisible(true); + undo_button.addActionListener(this); + + skill_button = new Button("Skill Level"); + skill_button.setSize(135, 25); + skill_button.setLocation(430, 10); + skill_button.setVisible(true); + skill_button.addActionListener(this); + + high_button = new Button("High Scores"); + high_button.setSize(135, 25); + high_button.setLocation(570, 10); + high_button.setVisible(true); + high_button.addActionListener(this); + + b_container.add(new_button); + b_container.add(undo_button); + b_container.add(skill_button); + b_container.add(high_button); + b_container.add(instruct_button); + + // Add the button container to the applet. + add(b_container); + + // Create the "Skill Level" dialog box. + skill_panel = new Panel(); + skill_panel.setSize(400, 300); + skill_panel.setLocation(200, 20); + skill_panel.setLayout(null); + + skill_label = new Label("Pick your skill level:"); + skill_label.setSize(200, 25); + skill_label.setLocation(25, 20); + skill_label.setVisible(true); + skill_panel.add(skill_label); + + group = new CheckboxGroup(); + Checkbox skill_1 = new Checkbox("Babe in the Woods ", group, false); + Checkbox skill_2 = new Checkbox("Walk and Chew Gum ", group, false); + Checkbox skill_3 = new Checkbox("Jeopardy Contestant ", group, false); + Checkbox skill_4 = new Checkbox("Rocket Scientist ", group, false); + Checkbox skill_5 = new Checkbox("Be afraid, be very afraid", group, true); + skill_1.setSize(170, 25); + skill_1.setLocation(80, 60); + skill_1.setVisible(true); + skill_2.setSize(170, 25); + skill_2.setLocation(80, 100); + skill_2.setVisible(true); + skill_3.setSize(170, 25); + skill_3.setLocation(80, 140); + skill_3.setVisible(true); + skill_4.setSize(170, 25); + skill_4.setLocation(80, 180); + skill_4.setVisible(true); + skill_5.setSize(170, 25); + skill_5.setLocation(80, 220); + skill_5.setVisible(true); + skill_return_button = new Button("Return"); + skill_return_button.setSize(120, 25); + skill_return_button.setLocation(300, 370); + skill_return_button.setVisible(false); + skill_return_button.addActionListener(this); + skill_panel.add(skill_1); + skill_panel.add(skill_2); + skill_panel.add(skill_3); + skill_panel.add(skill_4); + skill_panel.add(skill_5); + skill_panel.setVisible(false); + add(skill_return_button); + add(skill_panel); + + // Create the "Instructions" panel. + instruct_return_button = new Button("Return"); + instruct_return_button.setLocation(300, 370); + instruct_return_button.setSize(120, 25); + instruct_return_button.setVisible(false); + instruct_return_button.addActionListener(this); + instruct_text = + new TextArea(textString, 100, 200, TextArea.SCROLLBARS_VERTICAL_ONLY); + instruct_text.setSize(715, 350); + instruct_text.setLocation(0, 0); + instruct_text.setVisible(false); + add(instruct_text); + + add(instruct_return_button); + + high_panel = new Panel(); + high_panel.setSize(715, 350); + high_panel.setLocation(0, 0); + high_panel.setVisible(false); + high_panel.setLayout(null); + + high_label = new Label("High Scores"); + high_label.setLocation(330, 5); + high_label.setSize(200, 30); + high_label.setVisible(true); + high_panel.add(high_label); + + high_places = new Label[20]; + high_names = new Label[20]; + high_scores = new Label[20]; + for (int i=0; i<20; i++) { + high_places[i] = new Label(Integer.toString(i+1)); + high_places[i].setSize(20, 30); + high_places[i].setVisible(true); + high_names[i] = new Label(names[i]); + high_names[i].setSize(150, 30); + high_names[i].setVisible(true); + high_scores[i] = new Label(Integer.toString(scores[i])); + high_scores[i].setSize(150, 30); + high_scores[i].setVisible(true); + if (i<10) { + high_places[i].setLocation(70, i*30+40); + high_names[i].setLocation(100, i*30+40); + high_scores[i].setLocation(260, i*30+40); + } + else { + high_places[i].setLocation(425, (i-10)*30+40); + high_names[i].setLocation(455, (i-10)*30+40); + high_scores[i].setLocation(615, (i-10)*30+40); + } + high_panel.add(high_places[i]); + high_panel.add(high_names[i]); + high_panel.add(high_scores[i]); + } + high_return_button = new Button("Return"); + high_return_button.setSize(120, 25); + high_return_button.setLocation(300, 370); + high_return_button.setVisible(false); + high_return_button.addActionListener(this); + add(high_return_button); + add(high_panel); + + // Create the "Winner" dialog box + winner_panel = new Panel(); + winner_panel.setLayout(null); + winner_panel.setSize(600, 500); + winner_panel.setLocation(0, 0); + winner_return_button = new Button("Return"); + winner_return_button.setSize(120, 25); + winner_return_button.setLocation(300, 360); + winner_return_button.addActionListener(this); + winner_panel.add(winner_return_button); + winner_label = new Label(""); + winner_label.setSize(200, 30); + winner_label.setLocation(270, 110); + winner_score_label = new Label(""); + winner_score_label.setSize(200, 30); + winner_top_label = new Label("You have a score in the top 20."); + winner_top_label.setSize(200, 25); + winner_top_label.setLocation(260, 185); + winner_top_label.setVisible(false); winner_name_label = new Label("Enter your name here:"); + winner_name_label.setSize(150, 25); + winner_name_label.setLocation(260, 210); + winner_name_label.setVisible(false); + winner_name = new TextField(""); + winner_name.setSize(200, 30); + winner_name.setLocation(260, 240); + winner_name.setVisible(false); + winner_panel.add(winner_label); + winner_panel.add(winner_score_label); + winner_panel.add(winner_top_label); + winner_panel.add(winner_name_label); + winner_panel.add(winner_name); + winner_panel.setVisible(false); + add(winner_panel); + } + + public void destroy() { + universe.cleanup(); + } + + /** + * Create the scenegraph for the 3D view. + */ + public BranchGroup createScene3D() { + + // Define colors + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + Color3f red = new Color3f(0.80f, 0.20f, 0.2f); + Color3f ambient = new Color3f(0.25f, 0.25f, 0.25f); + Color3f diffuse = new Color3f(0.7f, 0.7f, 0.7f); + Color3f specular = new Color3f(0.9f, 0.9f, 0.9f); + Color3f ambientRed = new Color3f(0.2f, 0.05f, 0.0f); + Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f); + + // Create the branch group + BranchGroup branchGroup = new BranchGroup(); + + // Create the bounding leaf node + BoundingSphere bounds = + new BoundingSphere(new Point3d(0.0,0.0,0.0), 1000.0); + BoundingLeaf boundingLeaf = new BoundingLeaf(bounds); + branchGroup.addChild(boundingLeaf); + + // Create the background + Background bg = new Background(bgColor); + bg.setApplicationBounds(bounds); + branchGroup.addChild(bg); + + // Create the ambient light + AmbientLight ambLight = new AmbientLight(white); + ambLight.setInfluencingBounds(bounds); + branchGroup.addChild(ambLight); + + // Create the directional light + Vector3f dir = new Vector3f(-1.0f, -1.0f, -1.0f); + DirectionalLight dirLight = new DirectionalLight(white, dir); + dirLight.setInfluencingBounds(bounds); + branchGroup.addChild(dirLight); + + // Create the pole appearance + Material poleMaterial = + new Material(ambient, black, diffuse, specular, 110.f); + poleMaterial.setLightingEnable(true); + Appearance poleAppearance = new Appearance(); + poleAppearance.setMaterial(poleMaterial); + + // Create the transform group node + TransformGroup transformGroup = new TransformGroup(); + transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); + transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); + branchGroup.addChild(transformGroup); + + // Create the poles + Poles poles = new Poles(poleAppearance); + transformGroup.addChild(poles.getChild()); + + // Add the position markers to the transform group + transformGroup.addChild(positions.getChild()); + + // Let the positions object know about the transform group + positions.setTransformGroup(transformGroup); + + // Create the mouse pick and drag behavior node + PickDragBehavior behavior = new PickDragBehavior(canvas2D, canvas3D, positions, + branchGroup, transformGroup); + behavior.setSchedulingBounds(bounds); + transformGroup.addChild(behavior); + + return branchGroup; + } + + public void actionPerformed (ActionEvent event) { + + Object target = event.getSource(); + + // Process the button events. + if (target == skill_return_button) { + skill_panel.setVisible(false); + skill_return_button.setVisible(false); + c_container.setVisible(true); + b_container.setVisible(true); + newGame(); + } + else if (target == winner_return_button) { + if (winner_flag) { + String name = winner_name.getText(); + String tmp_name = new String(""); + int tmp_score = 0; + boolean insert_flag = false; + winner_flag = false; + for (int i=0; i<20; i++) { + if (insert_flag) { + name = names[i]; + score = scores[i]; + names[i] = tmp_name; + scores[i] = tmp_score; + tmp_name = name; + tmp_score = score; + } + if (!insert_flag && score > scores[i]) { + tmp_name = names[i]; + tmp_score = scores[i]; + scores[i] = score; + names[i] = name; + insert_flag = true; + } + high_names[i].setText(names[i]); + high_scores[i].setText(Integer.toString(scores[i])); + } + scoresString = new String(""); + int place; + for (int i=0; i<20; i++) { + place = (int) places[i]; + scoresString += Integer.toString(place); + scoresString += "\t"; + scoresString += names[i]; + scoresString += " "; + scoresString += Integer.toString(scores[i]); + scoresString += "\n"; + } + + if (appletFlag) { + // Use this section of code when writing the high + // scores file back to a server. Requires the use + // of a deamon on the server to receive the socket + // connection. + // + // Create the output stream. + // try { + // Socket socket = new Socket(host, port); + // outStream = new BufferedOutputStream + // (socket.getOutputStream(), 8192); + // } + // catch(IOException ioe) { + // System.out.println("Error: " + ioe.toString()); + // } + // System.out.println("Output stream opened"); + // + // Write the scores to the file back on the server. + // outText = scoresString.getBytes(); + // try { + // outStream.write(outText); + // outStream.flush(); + // outStream.close(); + // outStream = null; + // } + // catch (IOException ioe) { + // System.out.println("Error: " + ioe.toString()); + // } + // System.out.println("Output stream written"); + + try { + OutputStreamWriter outFile = + new OutputStreamWriter(new FileOutputStream("scores.txt")); + outFile.write(scoresString); + outFile.flush(); + outFile.close(); + outFile = null; + } + catch (IOException ioe) { + System.out.println("Error: " + ioe.toString()); + } + catch (Exception e) { + System.out.println("Error: " + e.toString()); + } + } + else { + + try { + OutputStreamWriter outFile = + new OutputStreamWriter(new FileOutputStream("scores.txt")); + outFile.write(scoresString); + outFile.flush(); + outFile.close(); + outFile = null; + } + catch (IOException ioe) { + System.out.println("Error: " + ioe.toString()); + } + } + } + winner_panel.setVisible(false); + winner_return_button.setVisible(false); + winner_label.setVisible(false); + winner_score_label.setVisible(false); + winner_name_label.setVisible(false); + winner_top_label.setVisible(false); + winner_name.setVisible(false); + c_container.setVisible(true); + b_container.setVisible(true); + } + else if (target == high_return_button) { + high_return_button.setVisible(false); + high_panel.setVisible(false); + c_container.setVisible(true); + b_container.setVisible(true); + } + else if (target == instruct_return_button) { + instruct_text.setVisible(false); + instruct_return_button.setVisible(false); + instruct_text.repaint(); + c_container.setVisible(true); + b_container.setVisible(true); + } + else if (target == undo_button) { + board.undo_move(); + canvas2D.repaint(); + } + else if (target == instruct_button) { + c_container.setVisible(false); + b_container.setVisible(false); + instruct_text.setVisible(true); + instruct_return_button.setVisible(true); + } + else if (target == new_button) { + newGame(); + } + else if (target == skill_button) { + c_container.setVisible(false); + b_container.setVisible(false); + skill_panel.setVisible(true); + skill_return_button.setVisible(true); + } + else if (target == high_button) { + // Read the high scores file. + if (appletFlag) { + try { + inStream = new BufferedInputStream + (new URL(getCodeBase(), "scores.txt").openStream(), 8192); + Reader read = new BufferedReader(new InputStreamReader(inStream)); + StreamTokenizer st = new StreamTokenizer(read); + st.whitespaceChars(32,44); + st.eolIsSignificant(false); + + int count = 0; + int token = st.nextToken(); + boolean scoreFlag = true; + String string; + while (count<20) { + places[count] = (int) st.nval; + string = new String(""); + token = st.nextToken(); + while (token == StreamTokenizer.TT_WORD) { + string += st.sval; + string += " "; + token = st.nextToken(); + } + names[count] = string; + scores[count] = (int) st.nval; + token = st.nextToken(); + count++; + } + inStream.close(); + } + catch(Exception ioe) { + System.out.println("Error: " + ioe.toString()); + } + } + else { + try { + inStream = new BufferedInputStream + (new FileInputStream("scores.txt")); + Reader read = new BufferedReader(new InputStreamReader(inStream)); + StreamTokenizer st = new StreamTokenizer(read); + st.whitespaceChars(32,44); + st.eolIsSignificant(false); + + int count = 0; + int token = st.nextToken(); + boolean scoreFlag = true; + String string; + while (count<20) { + places[count] = (int) st.nval; + string = new String(""); + token = st.nextToken(); + while (token == StreamTokenizer.TT_WORD) { + string += st.sval; + string += " "; + token = st.nextToken(); + } + names[count] = string; + scores[count] = (int) st.nval; + token = st.nextToken(); + count++; + } + inStream.close(); + } + catch(Exception ioe) { + System.out.println("Error: " + ioe.toString()); + } + } + c_container.setVisible(false); + b_container.setVisible(false); + high_panel.setVisible(true); + high_return_button.setVisible(true); + } + + Checkbox box = group.getSelectedCheckbox(); + String label = box.getLabel(); + if (label.equals("Babe in the Woods ")) { + board.set_skill_level(0); + } + else if (label.equals("Walk and Chew Gum ")) { + board.set_skill_level(1); + } + else if (label.equals("Jeopardy Contestant ")) { + board.set_skill_level(2); + } + else if (label.equals("Rocket Scientist ")) { + board.set_skill_level(3); + } + else if (label.equals("Be afraid, be very afraid")) { + board.set_skill_level(4); + } + } + + public void newGame() { + board.newGame(); + canvas2D.repaint(); + } + + public void start() { + if (appletFlag) showStatus("FourByFour"); + } + + public void winner(int player, int level, int nmoves, long time) { + + if (player == 1) { + score = level * level_weight + + (66 - nmoves) * move_weight - + (int) Math.min(time * time_weight, 5000); + winner_label.setText("Game over, you win!"); + winner_label.setLocation(290, 90); + winner_score_label.setText("Score = " + score); + winner_score_label.setVisible(true); + winner_score_label.setLocation(315, 120); + if (score > scores[19]) { + winner_name_label.setVisible(true); + winner_top_label.setVisible(true); + winner_name.setVisible(true); + winner_flag = true; + } + } + else { + winner_label.setText("Game over, the computer wins!"); + winner_label.setLocation(250, 150); + } + c_container.setVisible(false); + b_container.setVisible(false); + winner_panel.setVisible(true); + winner_label.setVisible(true); + winner_return_button.setVisible(true); + repaint(); + } + + /** + * Inner class used to "kill" the window when running as + * an application. + */ + static class killAdapter extends WindowAdapter { + public void windowClosing(WindowEvent event) { + System.exit(0); + } + } + + /** + * Main method, only used when running as an application. + */ + public static void main(String[] args) { + FourByFour.appletFlag = false; + new MainFrame(new FourByFour(), 730, 450); + } + +} diff --git a/src/FourByFour/FourByFour_plugin.html b/src/FourByFour/FourByFour_plugin.html new file mode 100644 index 0000000..55e1cf4 --- /dev/null +++ b/src/FourByFour/FourByFour_plugin.html @@ -0,0 +1,39 @@ +<HTML> +<HEAD> +<TITLE>Drag the mouse in the window</TITLE> +</HEAD> +<BODY BGCOLOR="#0C0C33"> +<!--"CONVERTED_APPLET"--> +<!-- CONVERTER VERSION 1.3 --> +<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" +WIDTH = 716 HEIGHT = 410 ALIGN = middle codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0"> +<PARAM NAME = CODE VALUE = "FourByFour.class" > + +<PARAM NAME="type" VALUE="application/x-java-applet;version=1.2.2"> +<PARAM NAME="scriptable" VALUE="false"> +<COMMENT> +<EMBED type="application/x-java-applet;version=1.2.2" CODE = "FourByFour.class" WIDTH = 716 HEIGHT = 410 ALIGN = middle scriptable=false pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html"><NOEMBED></COMMENT> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see "FourByFour" instead of this paragraph. +<hr> +</blockquote> +</NOEMBED></EMBED> +</OBJECT> + +<!-- +<APPLET CODE = "FourByFour.class" WIDTH = 716 HEIGHT = 410 ALIGN = middle> +<blockquote> +<hr> +If you were using a Java-capable browser, +you would see "FourByFour" instead of this paragraph. +<hr> +</blockquote> + +</APPLET> +--> +<!--"END_CONVERTED_APPLET"--> + +</BODY> +</HTML> diff --git a/src/FourByFour/ID.java b/src/FourByFour/ID.java new file mode 100644 index 0000000..0a33077 --- /dev/null +++ b/src/FourByFour/ID.java @@ -0,0 +1,59 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +class ID { + int id; + + public ID(int id) { + this.id = id; + } + + public int get() { + return id; + } + + public void set(int id) { + this.id = id; + } +} diff --git a/src/FourByFour/PickDragBehavior.java b/src/FourByFour/PickDragBehavior.java new file mode 100644 index 0000000..96d6352 --- /dev/null +++ b/src/FourByFour/PickDragBehavior.java @@ -0,0 +1,216 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import com.sun.j3d.utils.geometry.Sphere; + +/** + * Class: PickDragBehavior + * + * Description: Used to respond to mouse pick and drag events + * in the 3D window. + * + * Version: 1.0 + * + */ +public class PickDragBehavior extends Behavior { + + WakeupCriterion[] mouseEvents; + WakeupOr mouseCriterion; + int x, y; + int x_last, y_last; + double x_angle, y_angle; + double x_factor, y_factor; + Transform3D modelTrans; + Transform3D transformX; + Transform3D transformY; + TransformGroup transformGroup; + BranchGroup branchGroup; + Canvas2D canvas2D; + Canvas3D canvas3D; + Positions positions; + PickRay pickRay = new PickRay(); + SceneGraphPath sceneGraphPath[]; + Appearance highlight; + boolean parallel; + + PickDragBehavior(Canvas2D canvas2D, Canvas3D canvas3D, Positions positions, + BranchGroup branchGroup, TransformGroup transformGroup) { + + this.canvas2D = canvas2D; + this.canvas3D = canvas3D; + this.positions = positions; + this.branchGroup = branchGroup; + this.transformGroup = transformGroup; + + modelTrans = new Transform3D(); + transformX = new Transform3D(); + transformY = new Transform3D(); + + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + Color3f green = new Color3f(0.0f, 1.0f, 0.0f); + + highlight = new Appearance(); + highlight.setMaterial(new Material(green, black, green, white, 80.f)); + + parallel = true; + } + + public void initialize() { + x = 0; + y = 0; + x_last = 0; + y_last = 0; + x_angle = 0; + y_angle = 0; + x_factor = .02; + y_factor = .02; + + mouseEvents = new WakeupCriterion[2]; + mouseEvents[0] = new WakeupOnAWTEvent(MouseEvent.MOUSE_DRAGGED); + mouseEvents[1] = new WakeupOnAWTEvent(MouseEvent.MOUSE_PRESSED); + mouseCriterion = new WakeupOr(mouseEvents); + wakeupOn (mouseCriterion); + } + + public void processStimulus (Enumeration criteria) { + WakeupCriterion wakeup; + AWTEvent[] event; + int id; + int dx, dy; + + while (criteria.hasMoreElements()) { + wakeup = (WakeupCriterion) criteria.nextElement(); + if (wakeup instanceof WakeupOnAWTEvent) { + event = ((WakeupOnAWTEvent)wakeup).getAWTEvent(); + for (int i=0; i<event.length; i++) { + id = event[i].getID(); + if (id == MouseEvent.MOUSE_DRAGGED) { + + x = ((MouseEvent)event[i]).getX(); + y = ((MouseEvent)event[i]).getY(); + + dx = x - x_last; + dy = y - y_last; + + x_angle = dy * y_factor; + y_angle = dx * x_factor; + + transformX.rotX(x_angle); + transformY.rotY(y_angle); + + modelTrans.mul(transformX, modelTrans); + modelTrans.mul(transformY, modelTrans); + + transformGroup.setTransform(modelTrans); + + x_last = x; + y_last = y; + } + else if (id == MouseEvent.MOUSE_PRESSED) { + + x = x_last = ((MouseEvent)event[i]).getX(); + y = y_last = ((MouseEvent)event[i]).getY(); + + Point3d eyePos = new Point3d(); + canvas3D.getCenterEyeInImagePlate(eyePos); + + Point3d mousePos = new Point3d(); + canvas3D.getPixelLocationInImagePlate(x, y, mousePos); + + Transform3D transform3D = new Transform3D(); + canvas3D.getImagePlateToVworld(transform3D); + + transform3D.transform(eyePos); + transform3D.transform(mousePos); + + Vector3d mouseVec; + if (parallel) { + mouseVec = new Vector3d(0.f, 0.f, -1.f); + } + else { + mouseVec = new Vector3d(); + mouseVec.sub(mousePos, eyePos); + mouseVec.normalize(); + } + + pickRay.set(mousePos, mouseVec); + sceneGraphPath = branchGroup.pickAllSorted(pickRay); + + if (sceneGraphPath != null) { + for (int j=0; j<sceneGraphPath.length; j++) { + if (sceneGraphPath[j] != null) { + Node node = sceneGraphPath[j].getObject(); + if (node instanceof Shape3D) { + try { + ID posID = (ID) node.getUserData(); + if (posID != null) { + int pos = posID.get(); + positions.set(pos, Positions.HUMAN); + canvas2D.repaint(); + break; + } + } + catch (CapabilityNotSetException e) { + // Catch all CapabilityNotSet exceptions and + // throw them away, prevents renderer from + // locking up when encountering "non-selectable" + // objects. + } + } + } + } + } + } + } + } + } + wakeupOn (mouseCriterion); + } +} diff --git a/src/FourByFour/Poles.java b/src/FourByFour/Poles.java new file mode 100644 index 0000000..95a98fa --- /dev/null +++ b/src/FourByFour/Poles.java @@ -0,0 +1,80 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import java.applet.Applet; +import java.awt.event.*; +import javax.media.j3d.*; +import javax.vecmath.*; + +/** + * Class: Poles + * + * Description: Creates the "poles" in the 3D window. + * + * Version: 1.0 + * + */ +public class Poles extends Object { + + private Group group; + + public Poles(Appearance appearance) { + float x = -30.0f; + float z = -30.0f; + group = new Group(); + for(int i=0; i<4; i++) { + for(int j=0; j<4; j++) { + Cylinder c = new Cylinder(x, z, 1.0f, 60.0f, 10, appearance); + group.addChild(c.getShape()); + x += 20.0f; + } + x = -30.0f; + z += 20.0f; + } + } + + public Group getChild() { + return group; + } +} diff --git a/src/FourByFour/Positions.java b/src/FourByFour/Positions.java new file mode 100644 index 0000000..a669aae --- /dev/null +++ b/src/FourByFour/Positions.java @@ -0,0 +1,311 @@ +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + +import java.applet.Applet; +import java.awt.event.*; +import javax.media.j3d.*; +import javax.vecmath.*; +import java.util.BitSet; +import com.sun.j3d.utils.geometry.Sphere; + +/** + * Class: Positions + * + * Description: Creates the position markers. + * + * Version: 1.0 + * + */ +public class Positions extends Object { + + final static int UNOCCUPIED = 0; + final static int HUMAN = 1; + final static int MACHINE = 2; + final static int END = 3; + + private Vector3f point[]; + private Switch posSwitch; + private Switch humanSwitch; + private Switch machineSwitch; + private BitSet posMask; + private BitSet humanMask; + private BitSet machineMask; + private Group group; + private Material redMat; + private Material blueMat; + private Material yellowMat; + private Material whiteMat; + private Appearance redApp; + private Appearance blueApp; + private Appearance yellowApp; + private Appearance whiteApp; + private Board board; + private Sphere posSphere[]; + private BigCube cube[]; + private TransformGroup tgroup; + private boolean winnerFlag = false; + + public Positions() { + + // Define colors for lighting + Color3f white = new Color3f(1.0f, 1.0f, 1.0f); + Color3f black = new Color3f(0.0f, 0.0f, 0.0f); + Color3f red = new Color3f(0.9f, 0.1f, 0.2f); + Color3f blue = new Color3f(0.3f, 0.3f, 0.8f); + Color3f yellow = new Color3f(1.0f, 1.0f, 0.0f); + Color3f ambRed = new Color3f(0.3f, 0.03f, 0.03f); + Color3f ambBlue = new Color3f(0.03f, 0.03f, 0.3f); + Color3f ambYellow = new Color3f(0.3f, 0.3f, 0.03f); + Color3f ambWhite = new Color3f(0.3f, 0.3f, 0.3f); + Color3f specular = new Color3f(1.0f, 1.0f, 1.0f); + + // Create the red appearance node + redMat= new Material(ambRed, black, red, specular, 100.f); + redMat.setLightingEnable(true); + redApp = new Appearance(); + redApp.setMaterial(redMat); + + // Create the blue appearance node + blueMat= new Material(ambBlue, black, blue, specular, 100.f); + blueMat.setLightingEnable(true); + blueApp = new Appearance(); + blueApp.setMaterial(blueMat); + + // Create the yellow appearance node + yellowMat= new Material(ambYellow, black, yellow, specular, 100.f); + yellowMat.setLightingEnable(true); + yellowApp = new Appearance(); + yellowApp.setMaterial(yellowMat); + + // Create the white appearance node + whiteMat= new Material(ambWhite, black, white, specular, 100.f); + whiteMat.setLightingEnable(true); + whiteApp = new Appearance(); + whiteApp.setMaterial(whiteMat); + + // Load the point array with the offset (coordinates) for each of + // the 64 positions. + point = new Vector3f[64]; + int count = 0; + for (int i=-30; i<40; i+=20) { + for (int j=-30; j<40; j+=20) { + for (int k=-30; k<40; k+=20) { + point[count] = new Vector3f((float) k, (float) j, (float) i); + count++; + } + } + } + + // Create the switch nodes + posSwitch = new Switch(Switch.CHILD_MASK); + humanSwitch = new Switch(Switch.CHILD_MASK); + machineSwitch = new Switch(Switch.CHILD_MASK); + + // Set the capability bits + posSwitch.setCapability(Switch.ALLOW_SWITCH_READ); + posSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE); + + humanSwitch.setCapability(Switch.ALLOW_SWITCH_READ); + humanSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE); + + machineSwitch.setCapability(Switch.ALLOW_SWITCH_READ); + machineSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE); + + // Create the bit masks + posMask = new BitSet(); + humanMask = new BitSet(); + machineMask = new BitSet(); + + // Create the small white spheres that mark unoccupied + // positions. + posSphere = new Sphere[64]; + for (int i=0; i<64; i++) { + Transform3D transform3D = new Transform3D(); + transform3D.set(point[i]); + TransformGroup transformGroup = new TransformGroup(transform3D); + posSphere[i] = new Sphere(2.0f, Sphere.GENERATE_NORMALS | + Sphere.ENABLE_APPEARANCE_MODIFY, + 12, whiteApp); + Shape3D shape = posSphere[i].getShape(); + ID id = new ID(i); + shape.setUserData(id); + transformGroup.addChild(posSphere[i]); + posSwitch.addChild(transformGroup); + posMask.set(i); + } + + // Create the red spheres that mark the user's positions. + for (int i=0; i<64; i++) { + Transform3D transform3D = new Transform3D(); + transform3D.set(point[i]); + TransformGroup transformGroup = new TransformGroup(transform3D); + transformGroup.addChild(new Sphere(7.0f, redApp)); + humanSwitch.addChild(transformGroup); + humanMask.clear(i); + } + + // Create the blue cubes that mark the computer's positions. + for (int i=0; i<64; i++) { + Transform3D transform3D = new Transform3D(); + transform3D.set(point[i]); + TransformGroup transformGroup = new TransformGroup(transform3D); + BigCube cube = new BigCube(blueApp); + transformGroup.addChild(cube.getChild()); + machineSwitch.addChild(transformGroup); + machineMask.clear(i); + } + + // Set the positions mask + posSwitch.setChildMask(posMask); + humanSwitch.setChildMask(humanMask); + machineSwitch.setChildMask(machineMask); + + // Throw everything into a single group + group = new Group(); + group.addChild(posSwitch); + group.addChild(humanSwitch); + group.addChild(machineSwitch); + } + + public void setTransformGroup(TransformGroup transformGroup) { + tgroup = transformGroup; + } + + public Group getChild() { + return group; + } + + public void setBoard(Board board) { + this.board = board; + } + + public void winner() { + winnerFlag = true; + } + + public void noWinner() { + winnerFlag = false; + } + + public void setHighlight(int pos) { + posSphere[pos].setAppearance(yellowApp); + } + + public void clearHighlight(int pos) { + posSphere[pos].setAppearance(whiteApp); + } + + public void newGame() { + + // Clear the board + for (int i=0; i<64; i++) { + posMask.set(i); + humanMask.clear(i); + machineMask.clear(i); + } + posSwitch.setChildMask(posMask); + humanSwitch.setChildMask(humanMask); + machineSwitch.setChildMask(machineMask); + + // The following three lines fix a bug in J3D + Transform3D t = new Transform3D(); + tgroup.getTransform(t); + tgroup.setTransform(t); + + // Reset the winner flag + winnerFlag = false; + } + + public void set(int pos, int player) { + + // Stop accepting selections when the game + // is over. + if (winnerFlag) return; + + // Make sure the position is not occupied. + if (player == HUMAN) + if (!board.unoccupied(pos)) return; + + // Turn off the position marker for the given position + posMask.clear(pos); + posSwitch.setChildMask(posMask); + + // Turn on the player marker + if (player == Positions.HUMAN) { + humanMask.set(pos); + humanSwitch.setChildMask(humanMask); + board.selection(pos, Positions.HUMAN); + } + else { + machineMask.set(pos); + machineSwitch.setChildMask(machineMask); + } + + // The following three lines fix a bug in J3D + Transform3D t = new Transform3D(); + tgroup.getTransform(t); + tgroup.setTransform(t); + } + + public void clear(int pos) { + + // Turn on the position marker + posMask.set(pos); + posSwitch.setChildMask(posMask); + + // Turn off the player marker + humanMask.clear(pos); + humanSwitch.setChildMask(humanMask); + machineMask.clear(pos); + machineSwitch.setChildMask(machineMask); + + // The following three lines are a workaround for a bug + // in dev09 in which the transform3D of certain items are + // not updated properly. Scheduled to be fixed in dev10 + Transform3D t = new Transform3D(); + tgroup.getTransform(t); + tgroup.setTransform(t); + } + +} diff --git a/src/FourByFour/README b/src/FourByFour/README new file mode 100644 index 0000000..8ae0695 --- /dev/null +++ b/src/FourByFour/README @@ -0,0 +1,47 @@ +/* + * @(#)README 1.6 01/06/20 16:18:05 + * + * Copyright (c) 1996-2001 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN + * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR + * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR + * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that Software is not designed,licensed or intended + * for use in the design, construction, operation or maintenance of + * any nuclear facility. + */ + +FourByFour + +To run: + + appletviewer FourByFour.html + +Press the "Instructions" button to get instructions on +how to play FourByFour. diff --git a/src/FourByFour/build.xml b/src/FourByFour/build.xml new file mode 100644 index 0000000..cbf53a8 --- /dev/null +++ b/src/FourByFour/build.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> + +<!-- +/* + * $RCSfile$ + * + * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL + * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS + * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR + * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, + * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND + * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR + * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed, licensed or + * intended for use in the design, construction, operation or + * maintenance of any nuclear facility. + * + * $Revision$ + * $Date$ + * $State$ + */ + --> + +<project basedir="." default="compile"> + <target name="compile"> + <javac debug="true" deprecation="true" destdir="." srcdir="."> + </javac> + </target> + + <target name="all" depends="compile"> + </target> + + <target description="Clean all build products." name="clean"> + <delete> + <fileset dir="."> + <include name="**/*.class"/> + </fileset> + </delete> + </target> + +</project> diff --git a/src/FourByFour/instructions.txt b/src/FourByFour/instructions.txt new file mode 100644 index 0000000..f90f3c2 --- /dev/null +++ b/src/FourByFour/instructions.txt @@ -0,0 +1,93 @@ +/* + * @(#)instructions.txt 1.5 01/06/20 16:18:06 + * + * Copyright (c) 1996-2001 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any + * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND + * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY + * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN + * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR + * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR + * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that Software is not designed,licensed or intended + * for use in the design, construction, operation or maintenance of + * any nuclear facility. + */ + + Four By Four + +Description: + + A three dimensional game of tic-tac-toe on a 4x4x4 cube. + +Object: + + Be the first to score four in a row. + +Instructions: + + 1. It's you versus the computer. + + 2. There are five skill levels. Press the "Skill Level" button to select your level + of play. The program defaults to the hardest level. Changing the skill level in + the middle of a game will force the start of a new game. + + 3. The screen on the left is a 3D window. A mouse drag in this window will rotate the + view to any desired position. + + 4. The screen on the right is a 2D window which displays all 18 faces that exist in the + 4x4x4 array. + + 5. Click on any of the small gray spheres (in either the 2D or 3D window) to select a position. + + 6. Positions owned by you will be marked in red. Positions owned by the computer will be + marked in blue. + + 7. Click the "Undo Move" button to take back a move. + + 8. Clicking on any of words "Face X" in the 2D window will cause that particular face to highlight + in the 3D window. Clicking the word again will un-highlight the face. + + 9. The final score is based on skill level, number of moves, and time. Select the button + "High Scores" to see a list of the top 20 scores. There is no penalty for using the + undo button. + + 10. Good luck. + +General Strategy: + + 1. There are a 64 positions from which to choose. In total, there are 72 possible winning + combinations. + + 2. The outer four corners and the inner "core" of eight have the most winning combinations, + 7 each, and should perhaps be chosen first. + + 3. Use the 2D window to keep an eye on all the faces. + + 4. The computer plays well at the highest skill level (the default). There are, however, + faults in it's logic that can be exploited. Thus the human player can win even at the + highest skill level. In the beginning, however, you may want to start at the lower skill + levels and work your way up. diff --git a/src/FourByFour/scores.txt b/src/FourByFour/scores.txt new file mode 100644 index 0000000..0ebc31a --- /dev/null +++ b/src/FourByFour/scores.txt @@ -0,0 +1,20 @@ +1 Bart Simpson 5283 +2 Dwight Eisenhower 5105 +3 Ken 5061 +4 Barbie 2883 +5 DoubleMint Twins 2195 +6 Robin Hood 1772 +7 Jack Benny 1604 +8 Anonymous 1550 +9 Duke 1501 +10 Jack Paar 1499 +11 Barney 1488 +12 Mick Jagger 1472 +13 Howard Hughes 1329 +14 Bugs Bunny 1328 +15 Suzi Chapstick 1302 +16 Forest Gump 1244 +17 Alfred Hitchcock 1231 +18 Roman Polaski 1168 +19 Missy Giovi 1106 +20 Bill Joy 1002 |