home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / OPENSTEP / Games / NeXTGo-3.0-MIS / GoApp.m < prev    next >
Encoding:
Text File  |  1997-11-25  |  33.8 KB  |  1,370 lines

  1. #include "comment.header"
  2.  
  3. /* Generated by Interface Builder */
  4.  
  5. /* $Id: GoApp.m,v 1.4 1997/11/04 16:50:42 ergo Exp $ */
  6.  
  7. /*
  8.  * $Log: GoApp.m,v $
  9.  * Revision 1.4  1997/11/04 16:50:42  ergo
  10.  * ported to OpenStep
  11.  *
  12.  * Revision 1.3  1997/07/06 19:37:57  ergo
  13.  * actual version
  14.  *
  15.  * Revision 1.5  1997/06/03 23:00:58  ergo
  16.  * changed the appearance of the windows
  17.  *
  18.  * Revision 1.4  1997/05/30 18:44:15  ergo
  19.  * Added an Inspector
  20.  *
  21.  * Revision 1.3  1997/05/04 18:56:53  ergo
  22.  * added time control for moves
  23.  *
  24.  */
  25.  
  26. #import <AppKit/AppKit.h>
  27. #import <AppKit/NSPrintInfo.h>
  28.  
  29. /*   the following is included for the definition of fd_set below  */
  30. #include <sys/types.h>
  31. #include <sys/param.h>
  32. #include <sys/stat.h>
  33. #include <sys/time.h>
  34.  
  35. #include <string.h>
  36. #import "GoApp.h"
  37. #import "Board.h"
  38. #import "ClickCell.h"
  39. #import "GoServer.h"
  40. #include "igs.h"
  41. #include "godict.h"
  42.  
  43. #define CURRENT_VERSION    "Version 3.0"
  44.  
  45. unsigned char p[19][19], l[19][19], ma[19][19], ml[19][19];
  46. char special_characters[19][19], sgComment[2000], sgNodeName[200];
  47. int hist[19][19], currentMoveNumber;
  48. int rd, lib, play, pass, handicap, MAXX, MAXY;
  49. int currentStone, opposingStone, blackCaptured, whiteCaptured;
  50. int blackTerritory, whiteTerritory, SmartGoGameFlag, initialization;
  51. float black_Score, white_Score;
  52. int blackCapturedKoI, blackCapturedKoJ, whiteCapturedKoI, whiteCapturedKoJ;
  53. int bothSides, neitherSide, blackPassed, whitePassed, manScoreTemp;
  54. BOOL typeOfScoring, manualScoring, AGAScoring;
  55. int opn[9];                               // opening pattern flag
  56. BOOL gameType;
  57. BOOL finished, whiteSide, blackSide, printBold;
  58. gameHistory gameMoves[500];
  59. int lastMove, boardChanged;
  60. BOOL scoringGame, resultsDisplayed;
  61. node *SGgameMoves, *currentNode, *rootNode;
  62. FILE *smartGoInputFile;
  63. char *SGfile, *currentSGfilePosition;
  64. char *IGSStatusText, IGSPasswordText[20], IGSLoginText[20];
  65. GODICT *godict;
  66.  
  67. char *getpassword(void) {
  68.     return IGSPasswordText;
  69. }
  70.  
  71. char *getloginname(void) {
  72.     return IGSLoginText;
  73. }
  74.  
  75. void IGSSendString(char *s) {
  76.  
  77.     sendstr(s);
  78.     printBold = YES;
  79.     [NSApp SetIGSStatus:s];
  80.  
  81. }
  82.  
  83. void stripChar(char *s, char c) {
  84.     int i, j;
  85.  
  86.     i = 0;
  87.     while (i < strlen(s)) {
  88.         if (s[i] == c) {
  89.               for (j = i; j < strlen(s) - 1; j++)
  90.                 s[j] = s[j+1];
  91.               s[strlen(s) - 1] = 0;
  92.         }
  93.           else {
  94.               i++;
  95.         }
  96.     }
  97. }
  98.  
  99. int saveNeXTGoFile(const char *fileName)
  100. {
  101.   FILE *NGoFile;
  102.   int i, j;
  103.  
  104.   if ((NGoFile = fopen(fileName, "w")) == NULL)
  105.     return 1;
  106.  
  107.   fprintf(NGoFile, "%d\n", handicap);
  108.   fprintf(NGoFile, "%d\n", whiteSide);
  109.   fprintf(NGoFile, "%d\n", blackSide);
  110.   fprintf(NGoFile, "%d\n", MAXX);
  111.   fprintf(NGoFile, "%d\n", MAXY);
  112.   fprintf(NGoFile, "%d\n", currentStone);
  113.   fprintf(NGoFile, "%d\n", opposingStone);
  114.   fprintf(NGoFile, "%d\n", blackCaptured);
  115.   fprintf(NGoFile, "%d\n", whiteCaptured);
  116.   fprintf(NGoFile, "%d\n", blackCapturedKoI);
  117.   fprintf(NGoFile, "%d\n", blackCapturedKoJ);
  118.   fprintf(NGoFile, "%d\n", whiteCapturedKoI);
  119.   fprintf(NGoFile, "%d\n", whiteCapturedKoJ);
  120.   fprintf(NGoFile, "%d\n", bothSides);
  121.   fprintf(NGoFile, "%d\n", neitherSide);
  122.   fprintf(NGoFile, "%d\n", blackPassed);
  123.   fprintf(NGoFile, "%d\n", whitePassed);
  124.   fprintf(NGoFile, "%d\n", lastMove);
  125.   for (i = 0; i < 9; i++)
  126.     fprintf(NGoFile, "%d\n", opn[i]);
  127.   for (i = 0; i < lastMove; i++)
  128.     {
  129.       fprintf(NGoFile, "%d\n", gameMoves[i].numchanges);
  130.       fprintf(NGoFile, "%d\n", gameMoves[i].blackCaptured);
  131.       fprintf(NGoFile, "%d\n", gameMoves[i].whiteCaptured);
  132.       for (j = 0; j < gameMoves[i].numchanges; j++)
  133.     {
  134.       fprintf(NGoFile, "%d\n", gameMoves[i].changes[j].added);
  135.       fprintf(NGoFile, "%d\n", gameMoves[i].changes[j].color);
  136.       fprintf(NGoFile, "%d\n", gameMoves[i].changes[j].x);
  137.       fprintf(NGoFile, "%d\n", gameMoves[i].changes[j].y);
  138.     }
  139.     }
  140.  
  141.   fclose(NGoFile);
  142.  
  143.   return 0;
  144. }
  145.  
  146. int saveSmartGoFile(const char *fileName)
  147. {
  148.   FILE *NGoFile;
  149.   int i, j;
  150.  
  151.   if ((NGoFile = fopen(fileName, "w")) == NULL)
  152.     return 1;
  153.   fprintf(NGoFile, "(\n;\nGaMe[1]\nVieW[]\n");
  154.   fprintf(NGoFile, "SiZe[%d]\nKoMi[%3.1f]\nHAndicap[%d]", MAXX,
  155.       ((handicap == 0)?KOMI:0.5), handicap);
  156.   fprintf(NGoFile,"\nComment[ A game between ");
  157.  
  158.   if (gameType != LOCAL)
  159.     {
  160.       fprintf(NGoFile, "two people on the network.\n\n");
  161.     }
  162.   else if (neitherSide)
  163.     {
  164.       fprintf(NGoFile,"two human players.\n\n");
  165.     }
  166.   else if (bothSides)
  167.     {
  168.       fprintf(NGoFile,"two computer players.\n\n");
  169.     }
  170.   else
  171.     {
  172.       fprintf(NGoFile,"the computer and a human player.\n\n");
  173.     }
  174.  
  175.   if (finished)
  176.     {
  177.       fprintf(NGoFile,"        Result:  %s wins by %8.1f.]\n",
  178.           (black_Score > white_Score)?"Black":"White",
  179.           fabs(black_Score - white_Score));
  180.     }
  181.   else
  182.     {
  183.       fprintf(NGoFile, "]\n");
  184.     }
  185.  
  186.   if (handicap > 1)
  187.     {
  188.       int q, half;
  189.  
  190.       q = (MAXX < 13)?2:3;
  191.       half = (MAXX + 1)/2 - 1;
  192.  
  193.       switch (handicap) {
  194.       case 2:
  195.     fprintf(NGoFile, "AddBlack[%c%c][%c%c]\n", q+'a', MAXY-q-1+'a',
  196.         MAXX-q-1+'a', q+'a');
  197.     break;
  198.       case 3:
  199.     fprintf(NGoFile, "AddBlack[%c%c][%c%c][%c%c]\n", q+'a', MAXY-q-1+'a',
  200.         MAXX-q-1+'a', q+'a', q+'a', q+'a');
  201.     break;
  202.       case 4:
  203.     fprintf(NGoFile, "AddBlack[%c%c][%c%c][%c%c][%c%c]\n", q+'a',
  204.         MAXY-q-1+'a', MAXX-q-1+'a', q+'a', q+'a', q+'a', MAXX-q-1+'a',
  205.         MAXY-q-1+'a');
  206.     break;
  207.       case 5:
  208.     fprintf(NGoFile, "AddBlack[%c%c][%c%c][%c%c][%c%c][%c%c]\n", q+'a',
  209.         MAXY-q-1+'a', MAXX-q-1+'a', q+'a', q+'a', q+'a', MAXX-q-1+'a',
  210.         MAXY-q-1+'a', half+'a', half+'a');
  211.     break;
  212.       case 6:
  213.     fprintf(NGoFile, "AddBlack[%c%c][%c%c][%c%c][%c%c][%c%c][%c%c]\n",
  214.         q+'a', MAXY-q-1+'a', MAXX-q-1+'a', q+'a', q+'a', q+'a',
  215.         MAXX-q-1+'a', MAXY-q-1+'a', q+'a', half+'a', MAXX-q-1+'a',
  216.         half+'a');
  217.     break;
  218.       case 7:
  219.     fprintf(NGoFile, "AddBlack[%c%c][%c%c][%c%c][%c%c][%c%c][%c%c][%c%c]\n",
  220.         q+'a', MAXY-q-1+'a', MAXX-q-1+'a', q+'a', q+'a', q+'a',
  221.         MAXX-q-1+'a', MAXY-q-1+'a', q+'a', half+'a', MAXX-q-1+'a',
  222.         half+'a', half+'a', half+'a');
  223.     break;
  224.       case 8:
  225.     fprintf(NGoFile, "AddBlack[%c%c][%c%c][%c%c][%c%c][%c%c][%c%c][%c%c][%c%c]\n",
  226.         q+'a', MAXY-q-1+'a', MAXX-q-1+'a', q+'a', q+'a', q+'a',
  227.         MAXX-q-1+'a', MAXY-q-1+'a', q+'a', half+'a', MAXX-q-1+'a',
  228.         half+'a', half+'a', q+'a', half+'a', MAXY-q-1+'a');
  229.     break;
  230.       case 9:
  231.     fprintf(NGoFile, "AddBlack[%c%c][%c%c][%c%c][%c%c][%c%c][%c%c][%c%c][%c%c][%c%c]\n",
  232.         q+'a', MAXY-q-1+'a', MAXX-q-1+'a', q+'a', q+'a', q+'a',
  233.         MAXX-q-1+'a', MAXY-q-1+'a', q+'a', half+'a', MAXX-q-1+'a',
  234.         half+'a', half+'a', q+'a', half+'a', MAXY-q-1+'a', half+'a',
  235.         half+'a');
  236.     break;
  237.       }
  238.     }
  239.  
  240.   for (i = 0; i < lastMove; i++)
  241.     {
  242.       for (j = 0; j < gameMoves[i].numchanges; j++)
  243.     {
  244.       if (gameMoves[i].changes[j].added)
  245.         switch (gameMoves[i].changes[j].color)
  246.           {
  247.           case 1:
  248.         if (gameMoves[i].changes[j].x >= 0)
  249.           {
  250.             fprintf(NGoFile,";\nWhite[%c%c]\n",
  251.                 gameMoves[i].changes[j].x+'a',
  252.                 gameMoves[i].changes[j].y+'a');
  253.           }
  254.         else
  255.           {
  256.             fprintf(NGoFile, ";\nWhite[tt]\n");
  257.           }
  258.         break;
  259.           case 2:
  260.         if (gameMoves[i].changes[j].x >= 0)
  261.           {
  262.             fprintf(NGoFile,";\nBlack[%c%c]\n",
  263.                 gameMoves[i].changes[j].x+'a',
  264.                 gameMoves[i].changes[j].y+'a');
  265.           }
  266.         else
  267.           {
  268.             fprintf(NGoFile, ";\nBlack[tt]\n");
  269.           }
  270.         break;
  271.           }
  272.     }
  273.     }
  274.  
  275.   fprintf(NGoFile,")\n\n");
  276.   fclose(NGoFile);
  277.  
  278.   return 0;
  279. }
  280.  
  281. @implementation GoApp
  282.  
  283. + (void)initialize {
  284.  
  285.     id defaults;
  286.     
  287.     defaults = [NSUserDefaults standardUserDefaults];
  288.     [defaults setInteger:0 forKey:@"Handicap"];
  289.     [defaults setInteger:19 forKey:@"BoardSize"];
  290.     [defaults setBool:YES forKey:@"BlackSide"];
  291.     [defaults setBool:NO forKey:@"WhiteSide"];
  292.     [defaults setBool:YES forKey:@"ManualScoring"];
  293.     [defaults setBool:NO forKey:@"TypeOfScoring"];
  294.     [defaults setBool:NO forKey:@"AGAScoring"];
  295.  
  296.     [defaults synchronize];
  297.  
  298.     return;
  299. }
  300.  
  301. - (void)applicationDidFinishLaunching:(NSNotification *)notification {
  302. //    NSApplication *theApplication = [notification object];
  303.     id defaults;
  304.     char str[80];
  305.  
  306.     godict = NULL;
  307.     IGSfont = [ [NSFont fontWithName:@"Ohlfs" size:10] retain];
  308. //    IGSboldFont = [ [NSFont fontWithName:@"Ohlfs" size:10] retain];
  309.     IGSboldFont = [ [NSFont fontWithName:@"Helvetica-Bold" size:10] retain];
  310.     [gameWindow setMiniwindowImage:[ [NSImage imageNamed:@"NeXTGoFile"] retain]];
  311.     strcpy(str, "NeXTGo -- ");
  312.     strcat(str, CURRENT_VERSION);
  313.     [versionString setStringValue:[NSString stringWithCString:CURRENT_VERSION]];
  314.     [gameWindow setTitle:[NSString stringWithCString:str]];
  315.     [[IGSStatus documentView] setFont:IGSfont];
  316.     [[smartGoComments documentView] setFont:IGSfont];
  317. //    [controller initPanel];
  318.     
  319.     lastMove = 0;
  320.     gameType = LOCAL;
  321.  
  322.     defaults = [NSUserDefaults standardUserDefaults];
  323.     handicap     = [defaults integerForKey:@"Handicap"];
  324.     MAXX     = [defaults integerForKey:@"BoardSize"];
  325.     blackSide     = [defaults boolForKey:@"BlackSide"];
  326.     whiteSide     = [defaults boolForKey:@"WhiteSide"];
  327.     manualScoring = [defaults boolForKey:@"ManualScoring"];
  328.     typeOfScoring = [defaults boolForKey:@"TypeOfScoring"];
  329.     AGAScoring    = [defaults boolForKey:@"AGAScoring"];
  330.  
  331.     MAXY = MAXX;
  332.     manScoreTemp = manualScoring;
  333.  
  334.     [handicapSlider setIntValue:handicap];
  335.     [handicapText setIntValue:handicap];
  336.     [sizeSlider setIntValue:MAXX];
  337.     [sizeText setIntValue:MAXX];
  338.     [BlackPlayer selectCellAtRow:blackSide column:0];
  339.     [WhitePlayer selectCellAtRow:whiteSide column:0];
  340.     [scoringMethod selectCellAtRow:manualScoring column:0];
  341.     [scoringType selectCellAtRow:typeOfScoring column:0];
  342.     [AGAscoringMethodFlag setIntValue:AGAScoring];
  343.     [savePrefsFlag setIntValue:1];
  344.  
  345.     neitherSide = 0;
  346.     bothSides = 0;
  347.     manScoreTemp = manualScoring;
  348.  
  349.     if (!blackSide && !whiteSide)
  350.         neitherSide++;
  351.     if (blackSide && whiteSide)
  352.         bothSides++;
  353.  
  354.     [self NewGame:self];
  355.  
  356. #warning PrintingConversion:  The current PrintInfo object now depends on context. '[NSPrintInfo sharedPrintInfo]' used to be '[NSApp printInfo]'. This might want to be [[NSPrintOperation currentOperation] printInfo] or possibly [[PageLayout new] printInfo].
  357.     {
  358.         id newVar = [NSPrintInfo sharedPrintInfo];
  359.         [newVar setHorizontallyCentered:YES];
  360.         [newVar setVerticallyCentered:YES];
  361.     }
  362.  
  363.     [gameWindow setFrameAutosaveName:@"NeXTGoGameWindow"];
  364.     [gameWindow makeKeyAndOrderFront:self];
  365.     [gameInspector setFrameAutosaveName:@"NeXTGoGameInspector"];
  366.     [gameInspector makeKeyAndOrderFront:self];
  367.     [gameWindow makeKeyAndOrderFront:self];
  368.     [IGSPanel setFrameAutosaveName:@"NeXTGoIGSPanel"];
  369.  
  370.     SmartGoGameFlag = 0;
  371.     
  372.     CommandSender = nil;
  373. }
  374.  
  375. - showError: (const char *)errorMessage
  376. {
  377.   NSRunAlertPanel(@"NeXTGo Error", [NSString stringWithCString:errorMessage], @"OK", nil, nil);
  378.   return self;
  379. }
  380.  
  381. - UserPass:sender
  382. {
  383.   if (SmartGoGameFlag)
  384.     return self;
  385.  
  386.   [MainGoView passMove];
  387.  
  388.   return self;
  389. }
  390.  
  391. - stopGame:sender
  392. {
  393.   if (SmartGoGameFlag)
  394.     return self;
  395.  
  396.   [MainGoView stop:self];
  397.  
  398.   return self;
  399. }
  400.  
  401. - startGame:sender {
  402.     
  403.     if (SmartGoGameFlag)
  404.         return self;
  405.  
  406.     [MainGoView go:self];
  407.  
  408.     return self;
  409. }
  410.  
  411. - NewGame:sender
  412. {
  413.   int resp;
  414.  
  415.   if (gameType == IGSGAME)
  416.     {
  417.       NSRunAlertPanel(@"IGS Error", @"You must first close your IGS session before\n\
  418. beginning a new game.", @"OK", nil, nil);
  419.       return self;
  420.     }
  421.  
  422.   if (SmartGoGameFlag)
  423.     {
  424.       SmartGoGameFlag = 0;
  425.       [smartGoPanel close];
  426.     }
  427.  
  428.   gameType = LOCAL;
  429.  
  430.   if ((lastMove > 0) && (!finished))
  431.     {
  432.       resp = NSRunAlertPanel(@"NeXTGo Warning", @"A game is in process.  Do you wish to abandon it?", @"Abandon", @"Cancel", nil);
  433.  
  434.       if (resp == NSAlertAlternateReturn)
  435.     return self;
  436.     }
  437.  
  438.   [MainGoView startNewGame];
  439.   [MainGoView display];
  440.  
  441.   lastMove = 0;
  442.  
  443.   return self;
  444. }
  445.  
  446. - SetPreferences:sender {
  447.  
  448.     
  449.     handicap = [handicapSlider intValue];
  450.     MAXX = MAXY = [sizeSlider intValue];
  451.     blackSide = [BlackPlayer selectedRow];
  452.     whiteSide = [WhitePlayer selectedRow];
  453.     manualScoring = [scoringMethod selectedRow];
  454.     typeOfScoring = [scoringType selectedRow];
  455.     AGAScoring = [AGAscoringMethodFlag intValue];
  456.  
  457.     neitherSide = 0;
  458.     bothSides = 0;
  459.     manScoreTemp = manualScoring;
  460.  
  461.     if (!blackSide && !whiteSide)
  462.         neitherSide++;
  463.     if (blackSide && whiteSide)
  464.         bothSides++;
  465.  
  466.     [self NewGame:self];
  467.  
  468.     [prefPanel close];
  469.  
  470.     if ([savePrefsFlag intValue]) {
  471.             id defaults = [NSUserDefaults standardUserDefaults];
  472.             [defaults setInteger:handicap forKey:@"Handicap"];
  473.             [defaults setInteger:MAXX forKey:@"BoardSize"];
  474.             [defaults setBool:blackSide forKey:@"BlackSide"];
  475.             [defaults setBool:whiteSide forKey:@"WhiteSide"];
  476.             [defaults setBool:manualScoring forKey:@"ManualScoring"];
  477.             [defaults setBool:typeOfScoring forKey:@"TypeOfScoring"];
  478.             [defaults setBool:AGAScoring forKey:@"AGAScoring"];
  479.     }
  480.  
  481.     return self;
  482. }
  483.  
  484. - displayNewSGNode
  485. {
  486.   node *var_list, *current_var;
  487.  
  488.   [smartGoNodeNumber setIntValue:currentNode->nodenum];
  489.   [[smartGoComments documentView] setString:@""];
  490.   [[smartgoVariants documentView] setString:@""];
  491.   [self AddSGComment:sgComment];
  492.   [self SetSGNodeName:sgNodeName];
  493.  
  494.   [MainGoView display];
  495.   [MainGoView setblacksPrisoners:blackCaptured];
  496.   [MainGoView setwhitesPrisoners:whiteCaptured];
  497.  
  498.   for (var_list = currentNode->variants; var_list != NULL;
  499.        var_list = var_list->next_var)
  500.     {
  501.       char var_name[80];
  502.  
  503.       current_var = var_list;
  504.       while (current_var->properties == NULL)
  505.     {
  506.       current_var = forwardOneNode(current_var);
  507.     }
  508.  
  509.       sgNodeName[0] = 0;
  510.       buildToNode(current_var);
  511.       if (boardChanged)
  512.     [MainGoView doClick];
  513.       sprintf(var_name, "%d: %s", current_var->nodenum, sgNodeName);
  514.       [self AddSGVariantName:var_name];
  515.     }
  516.  
  517.   if (currentNode->variants != NULL)
  518.     {
  519.       sgNodeName[0] = 0;
  520.       sgComment[0] = 0;
  521.       buildToNode(currentNode);
  522.       if (boardChanged)
  523.     [MainGoView doClick];
  524.     }
  525.  
  526.   return self;
  527. }
  528.  
  529. - stepSmartGoFile:sender
  530. {
  531.   sgComment[0] = 0;
  532.   sgNodeName[0] = 0;
  533.  
  534.   currentNode = stepForward(currentNode);
  535.  
  536.   [self displayNewSGNode];
  537.  
  538.   return self;
  539. }
  540.  
  541. - stepBackSmartGoFile:sender
  542. {
  543.   sgComment[0] = 0;
  544.   sgNodeName[0] = 0;
  545.  
  546.   currentNode = stepBackward(currentNode);
  547.  
  548.   [self displayNewSGNode];
  549.  
  550.   return self;
  551. }
  552.  
  553. - jumpSmartGoFile:sender
  554. {
  555.   sgComment[0] = 0;
  556.   sgNodeName[0] = 0;
  557.  
  558.   currentNode = jumpForward(currentNode);
  559.  
  560.   [self displayNewSGNode];
  561.  
  562.   return self;
  563. }
  564.  
  565. - jumpBackSmartGoFile:sender
  566. {
  567.   sgComment[0] = 0;
  568.   sgNodeName[0] = 0;
  569.  
  570.   currentNode = jumpBackward(currentNode);
  571.  
  572.   [self displayNewSGNode];
  573.  
  574.   return self;
  575. }
  576.  
  577. - AddSGComment:(char *)s
  578. {
  579.   NSText *docView = [smartGoComments documentView];
  580.  
  581.   [docView setString:[[docView string] stringByAppendingString:[NSString stringWithCString:s]]];
  582.  
  583.   [docView selectAll:docView];
  584.   
  585.   [docView scrollRangeToVisible:[docView selectedRange]];
  586.  
  587.   return self;
  588. }
  589.  
  590. - AddSGVariantName:(char *)s
  591. {
  592.   NSText *docView = [smartgoVariants documentView];
  593.   NSString *retstr = @"\n", *aString;
  594.  
  595.   aString = [[[docView string] stringByAppendingString:retstr] stringByAppendingString:[NSString stringWithCString:s]];
  596.   aString = [aString stringByAppendingString:retstr];
  597.  
  598.   [docView selectAll:docView];
  599.  
  600.   [docView scrollRangeToVisible:[docView selectedRange]];
  601.  
  602.   return self;
  603. }
  604.  
  605. - SetSGNodeName:(char *)s
  606. {
  607.   [smartGoNodeName setStringValue:[NSString stringWithCString:s]];
  608.   [smartGoNodeName display];
  609.  
  610.   return self;
  611. }
  612.  
  613. - openNeXTGoFile:(const char*)aFile
  614. {
  615.     FILE *NGoFile;
  616.     int i, j, t, temp;
  617.  
  618.     if ((NGoFile = fopen(aFile, "r")) == NULL) {
  619.     return self;
  620.     }
  621.  
  622.     SmartGoGameFlag = 0;
  623.     fscanf(NGoFile, "%d", &handicap);
  624.     fscanf(NGoFile, "%d", &temp);
  625.     whiteSide = temp;
  626.     fscanf(NGoFile, "%d", &temp);
  627.     blackSide = temp;
  628.     fscanf(NGoFile, "%d", &MAXX);
  629.     fscanf(NGoFile, "%d", &MAXY);
  630.     [MainGoView startNewGame];
  631.     fscanf(NGoFile, "%d", &opposingStone);
  632.     fscanf(NGoFile, "%d", ¤tStone);
  633.     fscanf(NGoFile, "%d", &blackCaptured);
  634.     fscanf(NGoFile, "%d", &whiteCaptured);
  635.     fscanf(NGoFile, "%d", &blackCapturedKoI);
  636.     fscanf(NGoFile, "%d", &blackCapturedKoJ);
  637.     fscanf(NGoFile, "%d", &whiteCapturedKoI);
  638.     fscanf(NGoFile, "%d", &whiteCapturedKoJ);
  639.     fscanf(NGoFile, "%d", &bothSides);
  640.     fscanf(NGoFile, "%d", &neitherSide);
  641.     fscanf(NGoFile, "%d", &blackPassed);
  642.     fscanf(NGoFile, "%d", &whitePassed);
  643.     fscanf(NGoFile, "%d", &lastMove);
  644.     for (i = 0; i < 9; i++)
  645.       {
  646.         fscanf(NGoFile, "%d", &t);
  647.     opn[i] = t;
  648.       }
  649.     for (i = 0; i < MAXX; i++)
  650.       for (j = 0; j < MAXY; j++)
  651.     p[i][j] = hist[i][j] = 0;
  652.  
  653.     for (i = 0; i < lastMove; i++)
  654.       {
  655.     fscanf(NGoFile, "%d", &gameMoves[i].numchanges);
  656.     fscanf(NGoFile, "%d", &gameMoves[i].blackCaptured);
  657.     fscanf(NGoFile, "%d", &gameMoves[i].whiteCaptured);
  658.     gameMoves[i].changes = (struct change *)
  659.       malloc((size_t)sizeof(struct change)*gameMoves[i].numchanges);
  660.     for (j = 0; j < gameMoves[i].numchanges; j++)
  661.       {
  662.         fscanf(NGoFile, "%d", &gameMoves[i].changes[j].added);
  663.         fscanf(NGoFile, "%d", &gameMoves[i].changes[j].color);
  664.         fscanf(NGoFile, "%d", &gameMoves[i].changes[j].x);
  665.         fscanf(NGoFile, "%d", &gameMoves[i].changes[j].y);
  666.       }
  667.       }
  668.  
  669.     for (i = 0; i < lastMove; i++)
  670.       for (j = 0; j < gameMoves[i].numchanges; j++)
  671.     {
  672.       if (gameMoves[i].changes[j].added)
  673.         {
  674.           p[gameMoves[i].changes[j].x][gameMoves[i].changes[j].y] =
  675.         gameMoves[i].changes[j].color;
  676.           hist[gameMoves[i].changes[j].x][gameMoves[i].changes[j].y] = i;
  677.         }
  678.       else
  679.         {
  680.           p[gameMoves[i].changes[j].x][gameMoves[i].changes[j].y] = 0;
  681.         }
  682.     }
  683.     blackCaptured = gameMoves[lastMove-1].blackCaptured;
  684.     whiteCaptured = gameMoves[lastMove-1].whiteCaptured;
  685.  
  686.     [MainGoView refreshIO];
  687.  
  688.     [MainGoView resetButtons];
  689.  
  690.     fclose(NGoFile);
  691.  
  692.     [MainGoView lockFocus];
  693.     [[MainGoView window] flushWindow];
  694.     [MainGoView display];
  695.     [MainGoView unlockFocus];
  696.  
  697.     PSWait();
  698.  
  699.     return self;
  700. }
  701.  
  702. - initTranslator:sender {
  703.     char filename[MAXPATHLEN+1];
  704.     NSBundle   *bundle;
  705.  
  706.     bundle = [NSBundle bundleForClass:[self class]];
  707.     strcpy(filename, [[bundle bundlePath] cString] );
  708.     strcat(filename,"/Resources/");
  709.     strcat(filename,DEFDICT);
  710.  
  711.     if (godict == NULL) {
  712.         godict = load_dict(filename);
  713.  
  714.       if (godict == NULL)
  715.     {
  716.       NSRunAlertPanel(@"Translate Error", @"There is a problem opening the dictionary file.", @"OK", nil, nil);
  717.       return self;
  718.     }
  719.     }
  720.  
  721.   [translateWindow makeKeyAndOrderFront:self];
  722.   [translateWindow setMiniwindowImage:[NSImage imageNamed:@"NeXTGoFile"]];
  723.   [translateWindow display];
  724.   [translateTerm setStringValue:@""];
  725.   [translateTerm selectText:self];
  726.   [translateButton setEnabled:YES];
  727.   [[translateResults documentView] setString:@""];
  728.  
  729.   return self;
  730. }
  731.  
  732. - performTranslate:sender
  733. {
  734.   GODICT *d;
  735.   char term[80];
  736.   extern int termtypes, languages;
  737.  
  738.   strcpy(term, [[translateTerm stringValue] cString]);
  739.   if (strlen(term) == 0)
  740.     return self;
  741.  
  742.   termtypes = CD_MISC*[transTypeMISC intValue];
  743.   termtypes += CD_NAME*[transTypeNAME intValue];
  744.   termtypes += CD_CHAM*[transTypeCHAM intValue];
  745.   termtypes += CD_TECH*[transTypeTECH intValue];
  746.   termtypes += CD_POLI*[transTypePOLI intValue];
  747.   termtypes += CD_DIGI*[transTypeDIGI intValue];
  748.  
  749.   languages = LANG_DG*[transLangDG intValue];
  750.   languages += LANG_CP*[transLangCP intValue];
  751.   languages += LANG_JP*[transLangJP intValue];
  752.   languages += LANG_CH*[transLangCH intValue];
  753.   languages += LANG_RK*[transLangRK intValue];
  754.   languages += LANG_GB*[transLangGB intValue];
  755.   languages += LANG_NL*[transLangNL intValue];
  756.   languages += LANG_GE*[transLangGE intValue];
  757.   languages += LANG_FR*[transLangFR intValue];
  758.   languages += LANG_SV*[transLangSV intValue];
  759.  
  760.   [[translateResults documentView] setString:@""];
  761.   d = godict;
  762.  
  763.   while (d != NULL)
  764.     {
  765.       d = search_dict(d,term);
  766.       if (d != NULL)
  767.     {
  768.       [self translateOutput:d];
  769.       d = d->dct_next;
  770.     }
  771.     }
  772.   [translateTerm selectText:self];
  773.  
  774.   return self;
  775. }
  776.  
  777. - translateOutput:(GODICT *)d
  778. {
  779.   extern int languages;
  780.  
  781.   printBold = YES;
  782.   [self addTranslateResults:LB_CD];
  783.   switch(d->dct_type)
  784.     {
  785.     case CD_CHAM:
  786.       [self addTranslateResults:MSG_CHAM];
  787.       break;
  788.     case CD_TECH:
  789.       [self addTranslateResults:MSG_TECH];
  790.       break;
  791.     case CD_NAME:
  792.       [self addTranslateResults:MSG_NAME];
  793.       break;
  794.     case CD_POLI:
  795.       [self addTranslateResults:MSG_POLI];
  796.       break;
  797.     case CD_DIGI:
  798.       [self addTranslateResults:MSG_DIGI];
  799.       break;
  800.     default:
  801.       [self addTranslateResults:MSG_MISC];
  802.       break;
  803.     }
  804.  
  805.   [self addTranslateResults:"\n"];
  806.  
  807.   if (d->dct_jp && (languages & (LANG_JP)))
  808.     {
  809.       printBold = YES;
  810.       [self addTranslateResults:LB_JP];
  811.       [self addTranslateResults:d->dct_jp];
  812.       [self addTranslateResults:"\n"];
  813.     }
  814.   if (d->dct_ch && (languages & (LANG_CH)))
  815.     {
  816.       printBold = YES;
  817.       [self addTranslateResults:LB_CH];
  818.       [self addTranslateResults:d->dct_ch];
  819.       [self addTranslateResults:"\n"];
  820.     }
  821.   if (d->dct_rk && (languages & (LANG_RK)))
  822.     {
  823.       printBold = YES;
  824.       [self addTranslateResults:LB_RK];
  825.       [self addTranslateResults:d->dct_rk];
  826.       [self addTranslateResults:"\n"];
  827.     }
  828.   if (d->dct_gb && (languages & (LANG_GB)))
  829.     {
  830.       printBold = YES;
  831.       [self addTranslateResults:LB_GB];
  832.       [self addTranslateResults:d->dct_gb];
  833.       [self addTranslateResults:"\n"];
  834.     }
  835.   if (d->dct_nl && (languages & (LANG_NL)))
  836.     {
  837.       printBold = YES;
  838.       [self addTranslateResults:LB_NL];
  839.       [self addTranslateResults:d->dct_nl];
  840.       [self addTranslateResults:"\n"];
  841.     }
  842.   if (d->dct_ge && (languages & (LANG_GE)))
  843.     {
  844.       printBold = YES;
  845.       [self addTranslateResults:LB_GE];
  846.       [self addTranslateResults:d->dct_ge];
  847.       [self addTranslateResults:"\n"];
  848.     }
  849.   if (d->dct_fr && (languages & (LANG_FR)))
  850.     {
  851.       printBold = YES;
  852.       [self addTranslateResults:LB_FR];
  853.       [self addTranslateResults:d->dct_fr];
  854.       [self addTranslateResults:"\n"];
  855.     }
  856.   if (d->dct_fr && (languages & (LANG_SV)))
  857.     {
  858.       printBold = YES;
  859.       [self addTranslateResults:LB_SV];
  860.       [self addTranslateResults:d->dct_sv];
  861.       [self addTranslateResults:"\n"];
  862.     }
  863.   if (d->dct_dg && (languages & (LANG_DG)))
  864.     {
  865.       printBold = YES;
  866.       [self addTranslateResults:LB_DG];
  867.       [self addTranslateResults:"\n"];
  868.       [self addTranslateResults:d->dct_dg];
  869.       [self addTranslateResults:"\n"];
  870.     }
  871.   if (d->dct_cp && (languages & (LANG_CP)))
  872.     {
  873.       printBold = YES;
  874.       [self addTranslateResults:LB_CP];
  875.       [self addTranslateResults:d->dct_cp];
  876.       [self addTranslateResults:"\n"];
  877.     }
  878.  
  879.   [self addTranslateResults:"\n\n"];
  880.  
  881.   return self;
  882. }
  883.  
  884. - addTranslateResults:(char *)s {
  885.     NSString *aString;
  886.     
  887.     NSText *docView = [translateResults documentView];
  888.     aString = [docView string];
  889.     aString = [aString stringByAppendingString:[NSString stringWithCString:s]];
  890.     [docView setFont:IGSfont];
  891.     printBold = NO;
  892.     [docView selectAll:docView];
  893.  
  894.     [docView scrollRangeToVisible:[docView selectedRange]];
  895.  
  896.     return self;
  897. }
  898.  
  899. - openSmartGoFile:(const char*)aFile
  900. {
  901.       char dispFileName[80];
  902.       int i, j;
  903.       struct stat statbuf;
  904.  
  905.       if (gameType != LOCAL) {
  906.         NSRunAlertPanel(@"IGS Error", @"You must first close your IGS session before\n\
  907.          opening a Smart-Go file.", @"OK", nil, nil);
  908.           return self;
  909.       }
  910.  
  911.     if ((smartGoInputFile = fopen(aFile, "r")) == NULL) {
  912.               return self;
  913.     }
  914.  
  915.     SGgameMoves = NULL;
  916.     SmartGoGameFlag = 1;
  917.     initialization = 0;
  918.  
  919.     [smartGoPanel makeKeyAndOrderFront:self];
  920.     [smartGoPanel setMiniwindowImage:[NSImage imageNamed:@"NeXTGoFile"]];
  921.     [smartGoPanel display];
  922.     [stepForwardButton setEnabled:YES];
  923.  
  924.     stat(aFile, &statbuf);
  925.         SGfile = (char *) malloc ((size_t)statbuf.st_size+10);
  926.     if (fread(SGfile, statbuf.st_size, 1, smartGoInputFile) != 1) {
  927.             [self showError:"Error on Read"];
  928.             fclose(smartGoInputFile);
  929.             free(SGfile);
  930.             return self;
  931.     }
  932.  
  933.     fclose(smartGoInputFile);
  934.  
  935.     [MainGoView startNewGame];
  936.     [MainGoView setMess1:"Smart-Go Playback"];
  937.     j = 0;
  938.     for (i = 0; i < strlen(aFile); i++) {
  939.             if (aFile[i] == '/') {
  940.                 j = i;
  941.             }
  942.     }
  943.     for (i = j+1; i < strlen(aFile); i++) {
  944.             dispFileName[i-j-1] = aFile[i];
  945.     }
  946.     dispFileName[strlen(aFile) - j - 1] = 0;
  947.  
  948.     [MainGoView setMess2:dispFileName];
  949.  
  950.     rootNode = parse_tree(SGfile);
  951.     MAXX = MAXY = 19;
  952.     currentNode = stepForward(rootNode);
  953.     [self displayNewSGNode];
  954.  
  955.     PSWait();
  956.  
  957.     return self;
  958. }
  959.  
  960. - IGSSendCommand:sender {
  961.     NSRange aRange;
  962.     int i, blanks = 0;
  963.     NSString *aString;
  964.     if ([ [IGSCommand stringValue] length]) {
  965.         /* first we catch all commands which have a special implementation */
  966.         for (i=0; i< [ [IGSCommand stringValue] length]; i++)
  967.             if ([[IGSCommand stringValue] characterAtIndex:i] == ' ')
  968.                 blanks++;
  969.         aString = @"done";
  970.         aRange = [[IGSCommand stringValue] rangeOfString:aString];
  971.         if (!aRange.length + blanks ==
  972.             [[IGSCommand stringValue] length]){
  973.             [IGSCommand selectText:self];
  974.             [self IGSdone:self];
  975.         }
  976.         else {
  977.             aString = @"observe";
  978.             aRange = [[IGSCommand stringValue] rangeOfString:aString];
  979.             if (aRange.length + blanks ==
  980.                 [[IGSCommand stringValue] length]){
  981.                 [IGSCommand selectText:self];
  982.                 [self IGSobserve:self];
  983.             }
  984.             else {
  985.                 aString = @"unobserve";
  986.                 aRange = [[IGSCommand stringValue] rangeOfString:aString];
  987.                 if (aRange.length + blanks ==
  988.                     [[IGSCommand stringValue] length]){
  989.                     [IGSCommand selectText:self];
  990.                     [self IGSunobserve:self];
  991.                 }
  992.                 else {
  993.                     aString = @"load";
  994.                     aRange = [[IGSCommand stringValue] rangeOfString:aString];
  995.                     if (aRange.length + blanks ==
  996.                         [[IGSCommand stringValue] length]){
  997.                         [IGSCommand selectText:self];
  998.                         [self IGSOpenLoadGame:self];
  999.                     }
  1000.                     else {
  1001.                         aString = @"quit";
  1002.                         aRange = [[IGSCommand stringValue] rangeOfString:aString];
  1003.                         if (aRange.length + blanks ==
  1004.                             [[IGSCommand stringValue] length]){
  1005.                             [IGSCommand selectText:self];
  1006.                             [self IGSquit:self];
  1007.                         }
  1008.                         else {
  1009.                             IGSSendString((char *)[[IGSCommand stringValue] cString]);
  1010.                             IGSSendString("\n");
  1011.                         }
  1012.                     }
  1013.                 }
  1014.             }
  1015.         }
  1016.     }
  1017.     else {
  1018.         IGSSendString("\n");
  1019.     }        
  1020.  
  1021.     if (CommandSender != nil) {
  1022.     [CommandSender makeKeyAndOrderFront:self];
  1023.     CommandSender = nil;
  1024.     }
  1025.         
  1026.     return self;
  1027. }
  1028.  
  1029. - connect:(GoServer*)server {
  1030.     char s[80];
  1031.  
  1032.     sethost([[server serverName] cString]);
  1033.     setport([server port]);
  1034.     strcpy(IGSLoginText, [ [server login] cString]);
  1035.     strcpy(IGSPasswordText,[ [server password] cString]);
  1036.  
  1037.     if (SmartGoGameFlag) {
  1038.         SmartGoGameFlag = 0;
  1039.         [smartGoPanel close];
  1040.     }
  1041.  
  1042.     [[IGSStatus documentView] setString:@""];
  1043.     [IGSPanel makeKeyAndOrderFront:self];
  1044.     [IGSPanel setMiniwindowImage:[NSImage imageNamed:@"NeXTGoFile"]];
  1045.     [IGSCommand selectText:self];
  1046.  
  1047.   if (open_connection())
  1048.     {
  1049.       [self SetIGSStatus:"Unable to make a connection.\n"];
  1050.       gameType = LOCAL;
  1051.  
  1052.       NSRunAlertPanel(@"IGS Error", @"I was unable to make a connection.", @"OK", nil, nil);
  1053.       [IGSPanel close];
  1054.  
  1055.       return self;
  1056.     }
  1057.  
  1058.   [self SetIGSStatus:"Connection established."];
  1059.   sprintf(s, "Logging in as %s\n", IGSLoginText);
  1060.   [self SetIGSStatus:s];
  1061.  
  1062.   timer = [[NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(checkingNetTraffic:) userInfo:self repeats:YES] retain];
  1063.  
  1064.   gameType = IGSGAME;
  1065.   finished = YES;
  1066.   idle = 1;
  1067.   [loadMenuCell setEnabled:YES];
  1068.   [observeMenuCell setEnabled:YES];
  1069.  
  1070.   initparser();
  1071.  
  1072.   return self;
  1073. }
  1074.  
  1075. - checkNetTraffic {
  1076.     fd_set readers;
  1077.     struct timeval to;
  1078.     int sel;
  1079.  
  1080.     to.tv_sec = 0;
  1081.     to.tv_usec = 0;
  1082.  
  1083.     FD_ZERO(&readers);
  1084.     FD_SET(sock, &readers);
  1085.  
  1086.     sel = select(sock + 1, &readers, NULL, NULL, &to);
  1087.     if (FD_ISSET(sock, &readers))
  1088.         incomingserver();
  1089.  
  1090.     return self;
  1091. }
  1092.  
  1093. - SetIGSStatus:(char *)s {
  1094.     NSRange selected;
  1095.     id docView = [IGSStatus documentView];
  1096.     NSString *aString;
  1097.     aString = [NSString stringWithCString:s];
  1098.  
  1099.     NS_DURING
  1100.     if ((0 == [aString length]) ||
  1101.         ('\n' != [aString characterAtIndex:([aString length]-1)])) {
  1102.         aString = [aString stringByAppendingString:@"\n"];
  1103.     }
  1104.     NS_HANDLER
  1105. #ifdef DEBUG
  1106.     NSRunAlertPanel(@"Error Panel", @"%@", @"OK", nil, nil, localException);
  1107. #endif
  1108.     NS_ENDHANDLER
  1109.  
  1110.     [docView selectAll:nil];
  1111.     selected = [docView selectedRange];
  1112.     selected.location = selected.length;
  1113.     selected.length = 0;
  1114.     [docView setSelectedRange:selected];
  1115.     [docView replaceCharactersInRange:selected withString: aString];
  1116.     selected.length = [aString length];
  1117.     [docView setFont:IGSfont range:selected];
  1118.  
  1119.     if (printBold) {
  1120.         [docView setFont:IGSboldFont range:selected];
  1121.     }
  1122.     [docView scrollRangeToVisible:[docView selectedRange]];
  1123.  
  1124.     if (printBold) {
  1125.         [IGSCommand selectText:self];  
  1126.         printBold = NO;
  1127.     }
  1128.     //    [IGSCommand selectText:self];  
  1129.  
  1130.     return self;
  1131. }
  1132.  
  1133. - getGoView{
  1134.     return MainGoView;
  1135. }
  1136.  
  1137. - open:sender {
  1138.  
  1139.     id fileTypes;
  1140.  
  1141.     NSString *fileType1 = @"nextgo",
  1142.              *fileType2 = @"mgt";
  1143.  
  1144.     id open = [NSOpenPanel new];
  1145.  
  1146.     fileTypes = [NSArray arrayWithObjects:fileType1, fileType2, nil];
  1147.  
  1148.     [open setAllowsMultipleSelection:NO];
  1149.  
  1150.     if (NSOKButton == [open runModalForTypes:fileTypes]) {
  1151.         char * cc = rindex([[open filename] cString],'.');
  1152.         cc++;
  1153.         if (!strcmp(cc,"mgt")) {
  1154.             [self openSmartGoFile:[[open filename] cString] ];
  1155.         }
  1156.         else {
  1157.             [self openNeXTGoFile:[[open filename] cString] ];
  1158.         }
  1159.         return self;
  1160.     }
  1161.     return self;
  1162. }
  1163.  
  1164. - save:sender {
  1165.     char  aString[256] = "";
  1166.  
  1167.     id save = [NSSavePanel new];
  1168.  
  1169.     strcpy(aString, [[gameWindow title] cString]);
  1170.     stripChar(aString, ' ');
  1171.     stripChar(aString, '(');
  1172.     stripChar(aString, ')');
  1173.     stripChar(aString, '*');
  1174.         
  1175.  
  1176.     /* set the initial format */
  1177.  
  1178.     [self setFormat:formatMatrix];
  1179.  
  1180.     /* put format box in view */
  1181.     [save setAccessoryView:formatMatrix];
  1182.  
  1183.     if ((1 == [save runModalForDirectory:@"" file:@""])) {
  1184.         if ([[[formatMatrix selectedCell] title] isEqualToString:@"NeXTGo"]) {
  1185.               saveNeXTGoFile([[save filename] cString]);
  1186.               PSWait();
  1187.         }
  1188.         else {
  1189.               saveSmartGoFile([[save filename] cString]);
  1190.               PSWait();
  1191.         }
  1192.     }
  1193.     return self;
  1194. }
  1195.  
  1196. - setFormat:sender
  1197. {
  1198.     if ([[[sender selectedCell] title] isEqualToString:@"NeXTGo"]) {
  1199.             [[NSSavePanel savePanel] setRequiredFileType:@"nextgo"];
  1200.     }
  1201.     else {
  1202.          [[NSSavePanel savePanel] setRequiredFileType:@"mgt"];
  1203.     }
  1204.     return self;
  1205. }
  1206.  
  1207.  
  1208. /*
  1209.   The following methods are the various commands for the Internet Go Server
  1210.   */
  1211.  
  1212. - IGSobserve:sender
  1213. {
  1214.   message mess;
  1215.     NSRect frameRect = {{15, 30}, {497, 226}}, scrollRect = {{0, 0},{ 497, 226}};
  1216.   NSSize cellSize = {470, 30};
  1217.   char str[80];
  1218.   int i;
  1219.  
  1220.   idle = 0;
  1221.  
  1222.   getgames(&mess);
  1223.   observeMatrix = [[NSMatrix alloc] initWithFrame:frameRect mode:NSRadioModeMatrix cellClass:[ClickCell class] numberOfRows:0 numberOfColumns:1];
  1224.   [observeMatrix setCellSize:cellSize];
  1225.  
  1226.   for (i = 0; i < mess.gamecount; i++)
  1227.     {
  1228.       sprintf(str, "%3d -- %12s [%3s] vs. %12s [%3s] (%3d %d %d %3.1f)",
  1229.           mess.gamelist[i].gnum, mess.gamelist[i].white,
  1230.           mess.gamelist[i].wrank, mess.gamelist[i].black,
  1231.           mess.gamelist[i].brank, mess.gamelist[i].mnum,
  1232.           mess.gamelist[i].bsize, mess.gamelist[i].hcap,
  1233.           mess.gamelist[i].komi);
  1234.       [observeMatrix addRow];
  1235.       observeCell = [observeMatrix cellAtRow:i column:0];
  1236.       [observeCell setStringValue:[NSString stringWithCString:str]];
  1237.       [observeCell setAlignment:NSLeftTextAlignment];
  1238.     }
  1239.   [observeMatrix sizeToCells];
  1240.  
  1241.   observeScrollView = [[NSScrollView alloc] initWithFrame:scrollRect];
  1242.   [observeScrollView setHasVerticalScroller:YES];
  1243.   [observeScrollView setBorderType:NSBezelBorder];
  1244.   [observeScrollView setBackgroundColor:[NSColor lightGrayColor]];
  1245.   [observeScrollView setDocumentView:observeMatrix];
  1246.   [observeBox addSubview:observeScrollView];
  1247.   [observeMatrix scrollCellToVisibleAtRow:0 column:0];
  1248.   [observeBox display];
  1249.  
  1250.   [observeSelPanel makeKeyAndOrderFront:self];
  1251.  
  1252. //  [IGSCommand selectText:self];
  1253.   idle = 1;
  1254.  
  1255.   return self;
  1256. }
  1257.  
  1258. - cellClicked:theCell
  1259. {
  1260.   char str[80];
  1261.   int n;
  1262.  
  1263.   strcpy(str, [[theCell stringValue] cString]);
  1264.   sscanf(str, "%3d", &n);
  1265.  
  1266.   idle = 0;
  1267.   observegame(n);
  1268.   idle = 1;
  1269.  
  1270.   [unobserveMenuCell setEnabled:YES];
  1271.   [observeMenuCell setEnabled:NO];
  1272.   [loadMenuCell setEnabled:NO];
  1273.   [observeSelPanel close];
  1274.  
  1275.   return self;
  1276. }
  1277.  
  1278. - IGSunobserve:sender {
  1279.     
  1280.     sendstr("unobserve\n");
  1281.     [self SetIGSStatus:"Removing observe\n"];
  1282.     [unobserveMenuCell setEnabled:NO];
  1283.     [observeMenuCell setEnabled:YES];
  1284.     [loadMenuCell setEnabled:YES];
  1285.     [MainGoView gameCompleted];
  1286.     [MainGoView removeTE];
  1287.     
  1288.     return self;
  1289. }
  1290.  
  1291. - IGSOpenLoadGame:sender
  1292. {
  1293.   [LoadGameWindow makeKeyAndOrderFront:self];
  1294.   [LoadGameText selectText:self];
  1295.  
  1296.   return self;
  1297. }
  1298.  
  1299. - IGSLoadGame:sender
  1300. {
  1301.   idle = 0;
  1302.   loadgame((char *)[[LoadGameText stringValue] cString]);
  1303.   idle = 1;
  1304.  
  1305.   [LoadGameWindow close];
  1306.  
  1307.   return self;
  1308. }
  1309.  
  1310. - IGSdone:sender {
  1311.     
  1312.     int q;
  1313.     
  1314.     q = NSRunAlertPanel(@"Save", @"Save the current game to disk ?", @"Save...", @"Dont't save", nil);
  1315.     
  1316.     if (1==q) 
  1317.         [self save:self];
  1318.     
  1319.     IGSSendString("done\n");
  1320.     
  1321.     return self;
  1322. }
  1323.  
  1324. - IGSquit:sender {
  1325.  
  1326.     IGSSendString("quit");
  1327.     IGSSendString("\n");
  1328.     [self IGSunobserve:self];
  1329.  
  1330.     [timer invalidate]; [timer release];;
  1331.   
  1332.     [loadMenuCell setEnabled:NO];
  1333.     [observeMenuCell setEnabled:NO];
  1334.     [unobserveMenuCell setEnabled:NO];
  1335.     [MainGoView removeTE];
  1336.  
  1337.     gameType = LOCAL;
  1338.     [IGSPanel close];
  1339.  
  1340.     return self;
  1341. }
  1342.  
  1343. - sendCommand:sender {
  1344.     char buf[256];
  1345.  
  1346.     strcpy(buf, [[[sender selectedCell] title] cString]);
  1347.     buf[[[[sender selectedCell] title] length]] = '\n';
  1348.     buf[[[[sender selectedCell] title] length]+1] = '\0';    
  1349.     IGSSendString(buf);
  1350.  
  1351.     return self;
  1352. }
  1353.  
  1354. - gameCompleted {
  1355.     
  1356.     [MainGoView gameCompleted];    
  1357.     return self;
  1358. }
  1359.  
  1360. - setCommandSender:(id)aSender {
  1361.     CommandSender = aSender;
  1362.     return self;
  1363. }
  1364.  
  1365. - (void)checkingNetTraffic:(NSTimer *)aTimer {
  1366.     [[aTimer userInfo] checkNetTraffic];
  1367. }
  1368.  
  1369. @end
  1370.