//------------------------------------------------------- // // Written by Carl Haynes // // Submitted to Sun Microsystems for their // java.applet.Applet Contest 8/31/95 // //-------------------------------------------------------- import java.awt.*; public class crossword extends java.applet.Applet { final static int kAppWidth = 500; final static int kAppHeight = 550; final static int kBlockWidth = 30; final static int kBlockHeight = 30; final static int kBlocksWide = 15; final static int kBlocksHigh = 15; final static int kButtonWidth = 100; final static int kButtonHeight = 25; final static int kUp = 0; final static int kDown = 1; final static int kAcross = 0; final static int kPadding = 20; final static int kQuestionAreaHeight = 40; int gDirection = kAcross; int gCurX = 0; int gCurY = 0; int clipLeft = -1; int clipTop = -1; int clipWidth = -1; int clipHeight = -1; int gBlockMinY = 0; int gBlockMaxY = 0; int gBlockMinX = 0; int gBlockMaxX = 0; int gOldBlockMinY = 0; int gOldBlockMaxY = 0; int gOldBlockMinX = 0; int gOldBlockMaxX = 0; String letters[] = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "3", "6", "9"}; /*---------------------------------------------------------------*/ /*---------------------------------------------------------------*/ final static int layout[][] = { {21, -1, -1, -1, 2, -1, 3, -1, 4, -1, -1, -1, -1, -1, -1}, {-1, 1, 22, 00, 00, 00, 00, 00, 00, 00, -1, -1, 5, 00, 00}, {-1, -1, 00, -1, 00, -1, 00, -1, 00, -1, -1, -1, -1, -1, -1}, { 6, 00, 00, 00, 00, -1, 00, -1, 00, -1, -1, -1, -1, -1, -1}, {00, -1, 00, -1, 00, -1, 00, -1, 00, -1, 07, -1, -1, 8, -1}, {00, -1, 00, -1, 9, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00}, {00, -1, 00, -1, 00, -1, 00, -1, -1, -1, 00, -1, -1, 00, -1}, {10, 00, 00, 00, -1, 11, -1, 12, -1, -1, 00, -1, -1, 00, -1}, {00, -1, 00, -1, 13, 00, 00, 00, 00, 14, 00, 00, -1, 00, -1}, {00, -1, -1, -1, -1, 00, -1, 00, -1, 00, -1, -1, -1, 00, -1}, {00, -1, -1, 15, 00, 00, 00, 00, 00, 00, 16, -1, 17, 00, 00}, {00, -1, 18, -1, -1, 00, -1, 00, -1, -1, 00, -1, -1, 00, -1}, {-1, -1, 00, -1, -1, -1, -1, 00, -1, -1, 00, -1, -1, -1, -1}, {19, 00, 00, 00, 00, 00, 00, 00, -1, -1, 20, 00, 00, 00, 00}, {-1, -1, 00, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1} }; /* 22 */ final static String answers[][] = { {"A", " ", " ", " ", "T", " ", "H", " ", "S", " ", " ", " ", " ", " ", " "}, {" ", "C", "O", "U", "R", "T", "E", "O", "U", "S", " ", " ", "3", "6", "9"}, {" ", " ", "B", " ", "I", " ", "L", " ", "N", " ", " ", " ", " ", " ", " "}, {"C", "L", "E", "A", "N", " ", "P", " ", "S", " ", " ", " ", " ", " ", " "}, {"R", " ", "D", " ", "I", " ", "F", " ", "E", " ", "L", " ", " ", "C", " "}, {"E", " ", "I", " ", "T", "R", "U", "S", "T", "W", "O", "R", "T", "H", "Y"}, {"E", " ", "E", " ", "Y", " ", "L", " ", " ", " ", "Y", " ", " ", "E", " "}, {"K", "I", "N", "D", " ", "B", " ", "R", " ", " ", "A", " ", " ", "E", " "}, {"S", " ", "T", " ", "F", "R", "I", "E", "N", "D", "L", "Y", " ", "R", " "}, {"I", " ", " ", " ", " ", "A", " ", "C", " ", "E", " ", " ", " ", "F", " "}, {"D", " ", " ", "R", "E", "V", "E", "R", "E", "N", "T", " ", "F", "U", "N"}, {"E", " ", "C", " ", " ", "E", " ", "U", " ", " ", "A", " ", " ", "L", " "}, {" ", " ", "A", " ", " ", " ", " ", "I", " ", " ", "U", " ", " ", " ", " "}, {"R", "E", "V", "E", "R", "E", "N", "T", " ", " ", "T", "R", "O", "O", "P"}, {" ", " ", "E", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "} }; final static String gQuestionsAcross[] = { "", // 0 "5th point of the Scout Law", // 1 "", // 2 "", // 3 "", // 4 "The Best Troop in the World", // 5 "11th point of the Scout Law", // 6 "", // 7 "", // 8 "1st point of the Scout Law", // 9 "6th point of the Scout Law", // 10 "", // 11 "", // 12 "4th point of the Scout Law", // 13 "", // 14 "12th point of the Scout Law", // 15 "", // 16 "Scouting is", // 17 "", // 18 "12th point of the Scout Law", // 19 "Boy Scouts are a member of a", // 20 "Try the letter A", // 21 "", // 22 "", // 23 "", // 24 "", // 25 "", // 26 "", // 27 "", // 28 "", // 29 "", // 30 "", // 31 "", // 32 "", // 33 "", // 34 "", // 35 "", // 36 "", // 37 "", // 38 "", // 39 "", // 40 "", // 41 "", // 42 "", // 43 "", // 44 "", // 45 "", // 46 "", // 47 "", // 48 "", // 49 "", // 50 "", // 51 "", // 52 "", // 53 "", // 54 "", // 55 "", // 56 "", // 57 "", // 58 "", // 59 "", // 60 "", // 61 "", // 62 "", // 63 "", // 64 "", // 65 "", // 66 "", // 67 "", // 68 "", // 69 "", // 70 "", // 71 "", // 72 "", // 73 ""// 74 }; final static String gQuestionsDown[] = { "", // 0 "", // 1 "Father, Son & Holy Gost", // 2 "3rd point of the Scout Law", // 3 "Taps are played at", // 4 "The Best Troop in the World", // 5 "The camp is build beside the water way", // 6 "2nd point of the Scout Law", // 7 "8th point of the Scout Law", // 8 "", // 9 "", // 10 "10th point of the Scout Law", // 11 "To get more Scouts to join your Troop", // 12 "", // 13 "Cub Scout", // 14 "", // 15 "????-Line, a knot", // 16 "", // 17 "Bear Cubs live in a", // 18 "", // 19 "", // 20 "", // 21 "7th point of the Scout Law", // 22 "", // 23 "", // 24 "", // 25 "", // 26 "", // 27 "", // 28 "", // 29 "", // 30 "", // 31 "", // 32 "", // 33 "", // 34 "", // 35 "", // 36 "", // 37 "", // 38 "", // 39 "", // 40 "", // 41 "", // 42 "", // 43 "", // 44 "", // 45 "", // 46 "", // 47 "", // 48 "", // 49 "", // 50 "", // 51 "", // 52 "", // 53 "", // 54 "", // 55 "", // 56 "", // 57 "", // 58 "", // 59 "", // 60 "", // 61 "", // 62 "", // 63 "", // 64 "", // 65 "", // 66 "", // 67 ""// 68 }; /*---------------------------------------------------------------*/ String gGuesses[][] = new String[kBlocksWide][kBlocksHigh]; boolean gUpdateActiveAreaFlag = false; boolean gChangedActiveAreaFlag = false; Font buttonFont = null; Font tileFont = null; public void init() { int viewWidth; int left, top; resize((kBlocksWide * kBlockWidth) + (kPadding * 2), (kBlocksHigh * kBlockHeight) + (kPadding * 3) + kQuestionAreaHeight); NewGame(); buttonFont = new java.awt.Font("Courier", Font.PLAIN, 12); tileFont = new java.awt.Font("Helvetica", Font.PLAIN, 36); } /*---------------------------------------------------------------*/ public void NewGame() { for (int j = 0 ; j < kBlocksHigh ; j++) { for (int i = 0 ; i < kBlocksWide ; i++) { gGuesses[i][j] = ""; } } gOldBlockMinY = 0; gOldBlockMaxY = 0; gOldBlockMinX = 0; gOldBlockMaxX = 0; gDirection = kAcross; gCurX = 0; gCurY = 0; SetActiveBlock(gCurX, gCurY, gDirection); } /*----------------------------------------------*/ public void paint(Graphics g) { int left = 0; int right = kAppWidth - 1; int top = 0; int bottom = kAppHeight - 1; int tempLeft = 0; int tempRight = 0; int tempTop = 0; int viewWidth; int viewHeight; int buttonWidth = 0; int buttonHeight = 0; int buttonLeft = 0; int buttonTop = 0; int tileLeft; int tileTop; Font f = new java.awt.Font("Helvetica", 0, 12); g.setFont(f); Font numFont = new java.awt.Font("Helvetica", 0, 10); Font answerFont = new java.awt.Font("Helvetica", 0, 18); Font questionFont = new java.awt.Font("Courier", 0, 24); Font questionFont18 = new java.awt.Font("Courier", 0, 18); FontMetrics answerFontMetrics = g.getFontMetrics(answerFont); FontMetrics questionFontMetrics = g.getFontMetrics(questionFont); FontMetrics questionFont18Metrics = g.getFontMetrics(questionFont18); g.setColor(Color.lightGray); g.draw3DRect(0, 0, size().width - 1, size().height - 1, true); viewWidth = kBlocksWide * kBlockWidth; viewHeight = kBlocksHigh * kBlockHeight; top = kPadding; left = (size().width / 2) - (viewWidth / 2); g.setColor(Color.white); g.fill3DRect(left, top, viewWidth, kQuestionAreaHeight, false); g.setFont(f); String s = new String( String.valueOf(layout[gBlockMinY][gBlockMinX])); s = s.concat(" - "); if (gDirection == kAcross) s = s.concat("across"); else s = s.concat("down"); g.drawString(s, left + 5, top + 12); g.setFont(questionFont); if (gDirection == kAcross) { Font userFont = questionFont; if (questionFontMetrics.stringWidth(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]]) > viewWidth - 4) { userFont = questionFont18; g.setFont(questionFont18); } g.drawString(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]], (size().width / 2) - (g.getFontMetrics().stringWidth(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]]) / 2), (top + kQuestionAreaHeight) - 8); } else { Font userFont = questionFont; if (questionFontMetrics.stringWidth(gQuestionsDown[layout[gBlockMinY][gBlockMinX]]) > viewWidth - 4) { userFont = questionFont18; g.setFont(questionFont18); } g.drawString(gQuestionsDown[layout[gBlockMinY][gBlockMinX]], (size().width / 2) - (g.getFontMetrics().stringWidth(gQuestionsDown[layout[gBlockMinY][gBlockMinX]]) / 2), (top + kQuestionAreaHeight) - 8); } left = (size().width / 2) - (viewWidth / 2); top = (kPadding * 2) + kQuestionAreaHeight; for (int j = 0 ; j < kBlocksHigh ; j++) { for (int i = 0 ; i < kBlocksWide ; i++) { tempLeft = left + (i * kBlockWidth); tempTop = top + (j * kBlockHeight); if (InActiveBlock(i, j)) { if (i == gCurX && j == gCurY) g.setColor(Color.cyan); else g.setColor(Color.yellow); g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight); } else { g.setColor(Color.white); g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight); } g.setColor(Color.black); g.drawRect(tempLeft, tempTop, kBlockWidth , kBlockHeight ); if (layout[j][i] == -1){ g.setColor(Color.black); g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight); } else if (layout[j][i] != 0) { String numStr = String.valueOf(layout[j][i]); g.setFont(numFont); g.drawString(numStr, tempLeft + 4 , tempTop + 10); } // -- put in text if needed if (layout[j][i] != -1) { if (gGuesses[i][j].length() != 0) { int sWidth = 0; if (gGuesses[i][j].equalsIgnoreCase(answers[j][i]) == false) g.setColor(Color.red); else g.setColor(Color.black); sWidth = answerFontMetrics.stringWidth(gGuesses[i][j]); g.setFont(answerFont); g.drawString( gGuesses[i][j], tempLeft + ((kBlockWidth / 2) - (sWidth / 2)), (tempTop + kBlockHeight) - 6); } } } } } /*----------------------------------------------*/ void PaintWord(Graphics g, int minX, int maxX, int minY, int maxY) { int viewWidth = kBlocksWide * kBlockWidth; int viewHeight = kBlocksHigh * kBlockHeight; int left = (size().width / 2) - (viewWidth / 2); int top = (kPadding * 2) + kQuestionAreaHeight; int tempLeft = 0; int tempRight = 0; int tempTop = 0; left += (minX * kBlockWidth); top += (minY * kBlockHeight); /* g.clipRect( left, top, (kBlockWidth * (maxX - minX)) + kBlockWidth, (kBlockHeight * (maxY - minY)) + kBlockHeight); */ Font f = new java.awt.Font("Helvetica", 0, 12); g.setFont(f); Font numFont = new java.awt.Font("Helvetica", 0, 10); Font answerFont = new java.awt.Font("Helvetica", 0, 18); FontMetrics answerFontMetrics = g.getFontMetrics(answerFont); viewWidth = kBlocksWide * kBlockWidth; viewHeight = kBlocksHigh * kBlockHeight; left = (size().width / 2) - (viewWidth / 2); top = (kPadding * 2) + kQuestionAreaHeight; for (int j = minY ; j <= maxY ; j++) { for (int i = minX ; i <= maxX ; i++) { tempLeft = left + (i * kBlockWidth); tempTop = top + (j * kBlockHeight); if (InActiveBlock(i, j)) { if (i == gCurX && j == gCurY) g.setColor(Color.cyan); else g.setColor(Color.yellow); g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight); } else { g.setColor(Color.white); g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight); } g.setColor(Color.black); g.drawRect(tempLeft, tempTop, kBlockWidth , kBlockHeight ); if (layout[j][i] == -1) { g.setColor(Color.black); g.fillRect(tempLeft, tempTop, kBlockWidth, kBlockHeight); } else if (layout[j][i] != 0) { String numStr = String.valueOf(layout[j][i]); g.setFont(numFont); g.drawString(numStr, tempLeft + 4 , tempTop + 10); } // -- put in text if needed if (layout[j][i] != -1) { if (gGuesses[i][j].length() != 0) { int sWidth = 0; if (gGuesses[i][j].equalsIgnoreCase(answers[j][i]) == false) g.setColor(Color.red); else g.setColor(Color.black); sWidth = answerFontMetrics.stringWidth(gGuesses[i][j]); g.setFont(answerFont); g.drawString( gGuesses[i][j], tempLeft + ((kBlockWidth / 2) - (sWidth / 2)), (tempTop + kBlockHeight) - 6); } } } } } /*----------------------------------------------*/ void PaintQuestionArea(Graphics g) { Font f = new java.awt.Font("Helvetica", 0, 12); Font questionFont = new java.awt.Font("Courier", 0, 24); Font questionFont18 = new java.awt.Font("Courier", 0, 18); FontMetrics questionFontMetrics = g.getFontMetrics(questionFont); int viewWidth = kBlocksWide * kBlockWidth; int viewHeight = kBlocksHigh * kBlockHeight; int top = kPadding; int left = (size().width / 2) - (viewWidth / 2); //g.clipRect(left, top, viewWidth, kQuestionAreaHeight); g.setColor(Color.white); g.fill3DRect(left, top, viewWidth, kQuestionAreaHeight, false); g.setFont(f); String s = new String( String.valueOf(layout[gBlockMinY][gBlockMinX])); s = s.concat(" - "); if (gDirection == kAcross) s = s.concat("across"); else s = s.concat("down"); g.drawString(s, left + 5, top + 12); g.setFont(questionFont); int fontSize = 24; if (gDirection == kAcross) { Font userFont = questionFont; if (questionFontMetrics.stringWidth(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]]) > viewWidth - 4) { userFont = questionFont18; g.setFont(questionFont18); } g.drawString(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]], (size().width / 2) - (g.getFontMetrics().stringWidth(gQuestionsAcross[layout[gBlockMinY][gBlockMinX]]) / 2), (top + kQuestionAreaHeight) - 8); } else { Font userFont = questionFont; if (questionFontMetrics.stringWidth(gQuestionsDown[layout[gBlockMinY][gBlockMinX]]) > viewWidth - 4) { userFont = questionFont18; g.setFont(questionFont18); } g.drawString(gQuestionsDown[layout[gBlockMinY][gBlockMinX]], (size().width / 2) - (g.getFontMetrics().stringWidth(gQuestionsDown[layout[gBlockMinY][gBlockMinX]]) / 2), (top + kQuestionAreaHeight) - 8); } } /*----------------------------------------------*/ private boolean InActiveBlock(int x, int y) { if (x < gBlockMinX) return(false); if (x > gBlockMaxX) return(false); if (y < gBlockMinY) return(false); if (y > gBlockMaxY) return(false); return(true); } /*----------------------------------------------*/ private void SetActiveBlock(int x, int y, int direction) { int tempx; int tempy; gOldBlockMinY = gBlockMinY; gOldBlockMaxY = gBlockMaxY; gOldBlockMinX = gBlockMinX; gOldBlockMaxX = gBlockMaxX; if (direction == kAcross) { gBlockMinY = y; gBlockMaxY = y; tempx = x; while (tempx > 0 && layout[y][tempx] != -1) { tempx--; } if (tempx > 0) gBlockMinX = tempx + 1; else { if (layout[y][0] == -1) gBlockMinX = 1; else gBlockMinX = 0; } tempx = x; while (tempx < kBlocksWide && layout[y][tempx] != -1) { tempx++; } gBlockMaxX = tempx -1; } else { gBlockMinX = x; gBlockMaxX = x; tempy = y; while (tempy > 0 && layout[tempy][x] != -1) { tempy--; } if (tempy > 0) gBlockMinY = tempy + 1; else { if (layout[0][x] == -1) gBlockMinY = 1; else gBlockMinY = 0; } tempy = y; while (tempy < kBlocksHigh && layout[tempy][x] != -1) { tempy++; } gBlockMaxY = tempy -1; } } /*----------------------------------------------*/ public void update(Graphics g) { if (clipLeft != -1 && clipTop != -1) { //g.clipRect(clipLeft, clipTop, clipWidth, clipHeight); clipLeft = clipTop = clipWidth = clipHeight = -1; } if (gChangedActiveAreaFlag == false && gUpdateActiveAreaFlag == false) { paint(g); return; } if (gChangedActiveAreaFlag == true) { PaintQuestionArea(g); PaintWord(g, gOldBlockMinX, gOldBlockMaxX, gOldBlockMinY, gOldBlockMaxY); PaintWord(g, gBlockMinX, gBlockMaxX, gBlockMinY, gBlockMaxY); gChangedActiveAreaFlag = false; return; } //----------------------------------------------- if (gUpdateActiveAreaFlag == true) { gUpdateActiveAreaFlag = false; PaintWord(g, gBlockMinX, gBlockMaxX, gBlockMinY, gBlockMaxY); return; } } /*----------------------------------------------*/ private void beep() { play(getCodeBase(), "nope.au"); } /*----------------------------------------------*/ public boolean mouseDown(java.awt.Event evt, int x, int y) { int viewWidth = kBlocksWide * kBlockWidth; int left = (size().width / 2) - (viewWidth / 2); int top = (kPadding * 2) + kQuestionAreaHeight; requestFocus(); if (x < left) return false; if (y < top) return false; int j = y - top; j /= kBlockHeight; int i = x - left; i /= kBlockWidth; if (i >= 0 && i < kBlocksWide && j >= 0 && j < kBlocksHigh) { if (layout[j][i] != -1) { gCurX = i; gCurY = j; if (InActiveBlock(i, j)) { gUpdateActiveAreaFlag = true; repaint(); } else { SetActiveBlock(i, j, gDirection); gChangedActiveAreaFlag = true; repaint(); } return true; } } return true; } /*----------------------------------------------*/ public boolean mouseUp(java.awt.Event evt, int x, int y) { requestFocus(); return true; } /*----------------------------------------------*/ public boolean mouseDrag(java.awt.Event evt, int x, int y) { requestFocus(); return true; } /*----------------------------------------------*/ public boolean mouseExit(java.awt.Event evt) { return true; } /*----------------------------------------------*/ public boolean mouseEnter(java.awt.Event evt) { requestFocus(); return true; } /*----------------------------------------------*/ public boolean mouseMove(java.awt.Event evt, int x, int y) { requestFocus(); return true; } /*----------------------------------------------*/ public boolean keyDown(java.awt.Event evt, int key) { if ((key >= 'A' && key <= 'Z') || (key >= 'a' && key <= 'z')) { char charArray[] = new char[1]; charArray[0] = (char)key; gGuesses[gCurX][gCurY] = new String(charArray); gGuesses[gCurX][gCurY] = gGuesses[gCurX][gCurY].toUpperCase(); if (gDirection == kAcross) { if (gCurX < kBlocksWide - 1 && layout[gCurY][gCurX+1] != -1) gCurX++; } else { if (gCurY < kBlocksHigh - 1 && layout[gCurY + 1][gCurX] != -1) gCurY++; } gUpdateActiveAreaFlag = true; repaint(); return true; } switch ((char)key) { case ' ': ChangeDirection(); gChangedActiveAreaFlag = true; repaint(); break; case 0x08: if (gGuesses[gCurX][gCurY] != "") { gGuesses[gCurX][gCurY] = ""; gUpdateActiveAreaFlag = true; repaint(); } else { if (gDirection == kAcross) { if (gCurX != 0 && layout[gCurY][gCurX-1] != -1) { gCurX--; gGuesses[gCurX][gCurY] = ""; gUpdateActiveAreaFlag = true; repaint(); } } else { if (gCurY != 0 && layout[gCurY - 1][gCurX] != -1) { gCurY--; gGuesses[gCurX][gCurY] = ""; gUpdateActiveAreaFlag = true; repaint(); } } } break; default: beep(); break; } return true; } /*----------------------------------------------*/ int random(int max) { return (int)Math.floor(Math.random() * max); } /*----------------------------------------------*/ boolean PtInRect(int x, int y, int left, int top, int right, int bottom) { if (x < left) return(false); if (x > right) return(false); if (y < top) return(false); if (y > bottom) return(false); return(true); } /*----------------------------------------------*/ void ChangeDirection() { if (gDirection == kDown) { gDirection = kUp; } else gDirection = kDown; SetActiveBlock(gCurX, gCurY, gDirection); } }