home *** CD-ROM | disk | FTP | other *** search
/ MORE WinGames / WINGAMES.iso / winpool / coordina.c < prev    next >
C/C++ Source or Header  |  1992-12-22  |  14KB  |  524 lines

  1.  
  2. /*
  3.  * I. ARIT 1992 Hidirbeyli,AYDIN,TR.  09400 Golden,    CO,   USA. 80401 
  4.  *
  5.  *
  6.  * Copyright (C) 1992 Ismail ARIT 
  7.  *
  8.  * This file  is distributed in the hope that it will be useful, but without any
  9.  * warranty.  No author or distributor accepts responsibility to anyone for
  10.  * the consequences of using it or for whether it serves any particular
  11.  * purpose or works at all. 
  12.  *
  13.  *
  14.  * Everyone is granted permission to copy, modify and redistribute this file
  15.  * under the following conditions: 
  16.  *
  17.  * Permission is granted to anyone to make or distribute copies of the source
  18.  * code, either as received or modified, in any medium, provided that all
  19.  * copyright notices, permission and nonwarranty notices are preserved, and
  20.  * that the distributor grants the recipient permission for further
  21.  * redistribution as permitted by this document. 
  22.  *
  23.  * No part of this program can be used in any commercial product. 
  24.  */
  25.  
  26.  
  27. #include <windows.h>
  28. #include <stdio.h>
  29. #include <math.h>
  30. #include <malloc.h>
  31.  
  32. #include "definiti.h"
  33.  
  34. extern int      WhiteBallOut, BlackBallOut;
  35. extern void
  36. ClearTable(void);
  37. extern Distance ThisMuch;
  38.  
  39.  
  40. extern void
  41. Force_ToObject(Ball * first, Distance * TheirDistance, int type);
  42. extern Distance *
  43. DistanceChecker_Between(Ball * ThisBall, Ball * ThatBall);
  44. extern
  45. setbkcolor(int color);
  46. extern int
  47. get_color(char *name);
  48. extern void
  49. setcolor(int color);
  50. extern
  51. Fillcircle(int x, int y, int rad);
  52. extern void
  53. Fillrectangle(int x, int y, int xx, int yy);
  54. extern void
  55. SyncDisplay(void);
  56. extern Ball    *
  57. new__Ball(double Mass, double radious, float initX, float initY, double initVx, double initVy, double initVr);
  58. extern void
  59. LayTheFloor(void);
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67. static void
  68. Coordinator__ShowStaticPosition(Coordinator * this, HDC hdc)
  69. {
  70.     int             i;
  71.     for (i = 0; i < this->NumberOfObjects; i++)
  72.         this->Objects[i]->Show(this->Objects[i], hdc);
  73. }
  74.  
  75. static void
  76. Coordinator__HideStaticPosition(Coordinator * this, HDC hdc)
  77. {
  78.     int             i;
  79.     for (i = 0; i < this->NumberOfObjects; i++)
  80.         this->Objects[i]->Hide(this->Objects[i], hdc);
  81. }
  82.  
  83.  
  84.  
  85.  
  86.  
  87. static void
  88. Coordinator__OpenSpaceForObjects(Coordinator * this)
  89. {
  90.     /* eliminate this */
  91.     /*
  92.      * this -> Objects = (Ball *) malloc (this -> NumberOfObjects *
  93.      * sizeof (Ball)); 
  94.      */
  95. };
  96.  
  97.  
  98. static int
  99. Coordinator__RegisterThisObject(Coordinator * this, Ball * AnotherBall)
  100. {
  101.     this->ObjectCounter++;
  102.     if (this->ObjectCounter > this->NumberOfObjects) {
  103.         printf("To many Objects\n");
  104.         exit(0);
  105.     }
  106.     this->Objects[this->ObjectCounter] = AnotherBall;
  107.     this->Objects[this->ObjectCounter]->MyID = this->ObjectCounter;
  108.     return (this->ObjectCounter);
  109. };
  110.  
  111. static void
  112. Coordinator__GetTime(Coordinator * this, Timing time)
  113. {
  114.     int             i;
  115.     this->mytime.currenttime = 0.000000000;
  116.     this->mytime.totaltime = time.totaltime;
  117.     this->mytime.dt = time.dt;
  118.  
  119.     for (i = 0; i < this->NumberOfObjects; i++) {
  120.         this->Objects[i]->mytime.currenttime = this->mytime.currenttime;
  121.         this->Objects[i]->mytime.totaltime = this->mytime.totaltime;
  122.         this->Objects[i]->mytime.dt = this->mytime.dt;
  123.     }
  124.  
  125. };
  126.  
  127.  
  128.  
  129.  
  130.  
  131. static void
  132. Coordinator__AllowableBump(Coordinator * this, float bump)
  133. {
  134.     this->AllowableDmax = bump;
  135. };
  136.  
  137.  
  138.  
  139. static void
  140. Coordinator__UpDateObjectsInitials(Coordinator * this)
  141. {
  142.     int             i;
  143.  
  144.     /* dprintf ("Coordinator::UpDateObjectsInitials()..\n"); */
  145.     for (i = 0; i < this->NumberOfObjects; i++) {
  146.         this->Objects[i]->CurrentF.x = 0.00000000;
  147.         this->Objects[i]->CurrentF.y = 0.00000000;
  148.     }
  149. };
  150.  
  151.  
  152.  
  153. static void
  154. Coordinator__GetBoundary(Coordinator * this, Space limits)
  155. {
  156.     this->myspace.xmin = limits.xmin;
  157.     this->myspace.ymin = limits.ymin;
  158.     this->myspace.xmax = limits.xmax;
  159.     this->myspace.ymax = limits.ymax;
  160.  
  161.  
  162.  
  163.     /* I 'll just use ball class to create pockets */
  164.     this->Pocket[0] = new__Ball(0, POCKETRADIOUS, this->myspace.xmin, this->myspace.ymin, 0, 0, 0);
  165.     this->Pocket[1] = new__Ball(0, POCKETRADIOUS, this->myspace.xmin, this->myspace.ymax, 0, 0, 0);
  166.  
  167.     this->Pocket[2] = new__Ball(0, POCKETRADIOUS, this->myspace.xmax, this->myspace.ymin, 0, 0, 0);
  168.     this->Pocket[3] = new__Ball(0, POCKETRADIOUS, this->myspace.xmax, this->myspace.ymax, 0, 0, 0);
  169.     this->Pocket[4] = new__Ball(0, POCKETRADIOUS, this->myspace.xmin + (this->myspace.xmax - this->myspace.xmin) / 2, this->myspace.ymin, 0, 0, 0);
  170.     this->Pocket[5] = new__Ball(0, POCKETRADIOUS, this->myspace.xmin + (this->myspace.xmax - this->myspace.xmin) / 2, this->myspace.ymax, 0, 0, 0);
  171.  
  172.     /* these are for debuging , they don't mean anything */
  173.     this->Pocket[0]->MyID = 20;
  174.     this->Pocket[1]->MyID = 21;
  175.     this->Pocket[2]->MyID = 22;
  176.     this->Pocket[3]->MyID = 23;
  177.     this->Pocket[4]->MyID = 24;
  178.     this->Pocket[5]->MyID = 25;
  179.  
  180.  
  181. };
  182.  
  183. static void
  184. Coordinator__DrawPockets(Coordinator * this)
  185. {
  186.     /*
  187.      * int             i; LayTheFloor(); let's draw table
  188.      * Fillrectangle(this->Pocket[0]->CurrentL.x - POCKETRADIOUS,
  189.      * this->Pocket[0]->CurrentL.y - POCKETRADIOUS,
  190.      * this->Pocket[3]->CurrentL.x + POCKETRADIOUS * 2,
  191.      * this->Pocket[3]->CurrentL.y + POCKETRADIOUS * 2); 
  192.      *
  193.      * for (i = 0; i < 6; i++) Fillcircle(this->Pocket[i]->CurrentL.x,
  194.      * this->Pocket[i]->CurrentL.y, this->Pocket[i]->radius);
  195.      *
  196.      * SyncDisplay();
  197.      */
  198.  
  199. };
  200.  
  201.  
  202. static void
  203. Coordinator__CheckPockets(Coordinator * this)
  204. {
  205.     int             i, j;
  206.     Distance       *theDistance;
  207.     for (i = 0; i < 6; i++)    /* we got 6 pockets */
  208.         for (j = 0; j < this->NumberOfObjects; j++) {
  209.             theDistance = DistanceChecker_Between(this->Pocket[i], this->Objects[j]);
  210.  
  211.             /* this is where we check the balls with the pockets */
  212.             if (theDistance->amount > this->Objects[j]->checkRad) {
  213.                 this->Objects[j]->In = NO;    /* you are out Pal!.. */
  214.                 /* just put it away */
  215.                 this->Objects[j]->CurrentL.x = this->Objects[j]->MyID * 40 + 1000;
  216.                 this->Objects[j]->CurrentL.y = 1000;
  217.                 this->Objects[j]->CurrentV.x = 0.000;
  218.                 this->Objects[j]->CurrentV.y = 0.000;
  219.  
  220.  
  221.             }
  222.         }
  223. };
  224.  
  225.  
  226.  
  227.  
  228. static void
  229. Coordinator__GetGameType(Coordinator * this, int Type)
  230. {
  231.     this->GameType = Type;
  232.     /* if (this->GameType == SIXTEENBALL){ */
  233.     this->CheckCondition = Coordinator__CheckPockets;
  234.     this->DrawPockets = Coordinator__DrawPockets;
  235.     /*
  236.      * } else { this->CheckCondition = Coordinator__CheckHits;
  237.      * this->DrawPockets = Coordinator__DummyFunction; }
  238.      *
  239.      */
  240. };
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247. static void
  248. Coordinator__CheckInitialLocations(Coordinator * this)
  249. {
  250.     int             j, i;
  251.     Distance       *theDistance;
  252.  
  253.     for (i = 0; i < this->NumberOfObjects - 1; i++)
  254.         for (j = i + 1; j < this->NumberOfObjects; j++) {
  255.             theDistance = DistanceChecker_Between(this->Objects[i], this->Objects[j]);
  256.             if (theDistance->amount > 0) {
  257.                 printf("Overlaping objects %d and %d \n", i, j);
  258.                 exit(0);
  259.             }
  260.         }
  261.  
  262. };
  263.  
  264.  
  265. static void
  266. Coordinator__AdvanceOneStep(Coordinator * this)
  267. {
  268.  
  269.     int             j = 0, i;
  270.     Distance       *theDistance;
  271.  
  272.     /* dprintf ("Coordinator::AdvanceOneStep()..\n"); */
  273.     for (i = 0; i < this->NumberOfObjects - 1; i++)
  274.         for (j = i + 1; j < this->NumberOfObjects; j++) {
  275.             theDistance = DistanceChecker_Between(this->Objects[i], this->Objects[j]);
  276.             if (theDistance->amount > 0) {
  277.  
  278.               /*    if (theDistance->amount > 5)
  279.                     printf("too much overlap %d %d \n", i, j);
  280.                 */
  281.                 /* apply reaction */
  282.                 Force_ToObject(this->Objects[i], theDistance, REACTION);
  283.                 /* apply action */
  284.                 Force_ToObject(this->Objects[j], theDistance, ACTION);
  285.  
  286.             }
  287.         }
  288.  
  289.  
  290.  
  291. };
  292.  
  293.  
  294.  
  295. static void
  296. Coordinator__CheckObjectsForTheSpace(Coordinator * this)
  297. {
  298.     int             i;
  299.     /* don't get confused, this is just to confine balls on the table */
  300.  
  301.     for (i = 0; i < this->NumberOfObjects; i++) {
  302.         if (
  303.             (this->Objects[i]->CurrentL.x + this->Objects[i]->radius) >= this->myspace.xmax ||
  304.             (this->Objects[i]->CurrentL.x - this->Objects[i]->radius) < this->myspace.xmin
  305.             )
  306.             this->Objects[i]->CurrentV.x *= -1;
  307.         if (
  308.             (this->Objects[i]->CurrentL.y + this->Objects[i]->radius) >= this->myspace.ymax ||
  309.             (this->Objects[i]->CurrentL.y - this->Objects[i]->radius) < this->myspace.ymin
  310.             )
  311.             this->Objects[i]->CurrentV.y *= -1;
  312.  
  313.     }
  314.  
  315.  
  316. };
  317.  
  318.  
  319.  
  320.  
  321.  
  322. static void
  323. Coordinator__CheckSpeedsAndCalculateK(Coordinator * this)
  324. {
  325.     float          MaxSpeed = 0.00000, CorrespondingMass = 0.00000;
  326.     int             i;
  327.  
  328.  
  329.     if (this->AllowableDmax == 0.0000000) {
  330.         printf("\n Missing Dmax, Not able to calculate K, Exiting....\n");
  331.         exit(0);
  332.     }
  333.     MaxSpeed = SPEEDLIMIT;
  334.     CorrespondingMass = PAYLOAD;
  335.  
  336.  
  337.     this->kConstant = CorrespondingMass * pow(MaxSpeed, 2.) / pow(this->AllowableDmax, 2.);
  338.  
  339.     for (i = 0; i < this->NumberOfObjects; i++)
  340.         this->Objects[i]->kConstant = this->kConstant;
  341.  
  342.  
  343.     dprintf("Max Speed = %f  kKons %f Dmax %f \n", MaxSpeed,
  344.         this->kConstant,
  345.         this->AllowableDmax);
  346.  
  347. };
  348.  
  349.  
  350.  
  351. static void
  352. Coordinator__ShowObjects(Coordinator * this, HDC hdc)
  353. {
  354.     int             i;
  355.     for (i = 0; i < this->NumberOfObjects; i++)
  356.         this->Objects[i]->MoveToNextLocation(this->Objects[i], hdc);
  357. };
  358.  
  359. /* another quick fix to mix the balls */
  360. int             which[15] = {2, 15, 3, 14, 4, 13, 5, 12, 1, 11, 7, 10, 8, 9, 0};
  361.  
  362. static void
  363. Coordinator__ArrangeBalls(Coordinator * this)
  364. {
  365.     int             i, j, counter = 0, ii;
  366.  
  367.  
  368.     /* this is what happens when you click on 'newgame' */
  369.  
  370.     /* for white ball */
  371.     this->Objects[0]->CurrentL.x = 460;
  372.     this->Objects[0]->CurrentL.y = 180;
  373.     /* black ball  will be somewhere in the middle */
  374.     this->Objects[6]->CurrentL.x = 200;
  375.     this->Objects[6]->CurrentL.y = 180;
  376.  
  377.     /* for the others */
  378.     for (j = 0; j < 2; j++)
  379.         for (i = 0; i < 4; i++) {
  380.  
  381.             ii = (j == 0) ? (i + 1) : (-i - 1);
  382.             this->Objects[which[counter]]->CurrentL.x = 200 - (i + 1) * 16;
  383.             this->Objects[which[counter]]->CurrentL.y = 180 - (ii) * 14;
  384.             counter++;
  385.  
  386.         }
  387.  
  388.     this->Objects[which[counter]]->CurrentL.x = 200 - 32;
  389.     this->Objects[which[counter]]->CurrentL.y = 180;
  390.     counter++;
  391.  
  392.     for (j = 0; j < 2; j++)
  393.         for (i = 0; i < 2; i++) {
  394.  
  395.             ii = (j == 0) ? (i + 1) : (-i - 1);
  396.             this->Objects[which[counter]]->CurrentL.x = 170 - (i + 1) * 16;
  397.             this->Objects[which[counter]]->CurrentL.y = 180 - (ii) * 14;
  398.             counter++;
  399.  
  400.         }
  401.  
  402.     this->Objects[which[counter]]->CurrentL.x = 135;
  403.     this->Objects[which[counter]]->CurrentL.y = 180;
  404.  
  405.  
  406.  
  407.  
  408.  
  409. };
  410.  
  411. static void
  412. Coordinator__StillMoving(Coordinator * this)
  413. {
  414.     int             i;
  415.     int             Movelist = 0;
  416.     for (i = 0; i < this->NumberOfObjects; i++) {
  417.         if (this->Objects[i]->Stopped == NO)
  418.             Movelist++;
  419.     }
  420.  
  421.     if (Movelist)
  422.         this->AllStopped = NO;
  423.     else
  424.         this->AllStopped = YES;
  425.  
  426. };
  427.  
  428. static void
  429. Coordinator__InitConfig(Coordinator * this, HDC hdc)
  430. {
  431.     int             i;
  432.     if (this->GameType == SIXTEENBALL)
  433.         this->ArrangeBalls(this);
  434.     this->CheckInitialLocations(this);
  435.     this->ShowStaticPosition(this, hdc);
  436.  
  437.     for (i = 0; i < this->NumberOfObjects; i++) {
  438.         this->Objects[i]->Stopped = NO;
  439.         this->Objects[i]->In = YES;
  440.         this->Objects[i]->ShowOut = NO;
  441.         this->Objects[i]->NeedOneMoreDrawing = YES;
  442.     }
  443.     WhiteBallOut = BlackBallOut = NO;
  444.  
  445. };
  446.  
  447.  
  448.  
  449. static void
  450. Coordinator__StartAction(Coordinator * this, HDC hdc)
  451. {
  452.  
  453.     int             Counter = 0;
  454.     int             CounterForPocket = 0;
  455.  
  456.     this->mytime.currenttime = 0.000;
  457.     this->AllStopped = NO;
  458. #define CHECKPOCKETDENSITY  4
  459.     /* dprintf ("Coordinator::StartAction()..\n"); */
  460.     while (!this->AllStopped) {
  461.         this->CheckObjectsForTheSpace(this);    /* table boundaries */
  462.         this->UpDateObjectsInitials(this);    /* init forces */
  463.         this->AdvanceOneStep(this);    /* do checkups and advance */
  464.         this->mytime.currenttime += this->mytime.dt;
  465.         this->ShowObjects(this, hdc);    /* show balls */
  466.         CounterForPocket++;
  467.         if (!(CounterForPocket % CHECKPOCKETDENSITY))
  468.             this->CheckCondition(this);    /* new locations in pockets ? */
  469.         Counter++;
  470.         if (!(Counter % CHECKMOVEDENSITY))
  471.             this->StillMoving(this);    /* make sure everybody
  472.                              * stopped */
  473.  
  474.     }
  475.  
  476. };
  477.  
  478.  
  479.  
  480.  
  481.  
  482. Coordinator    *
  483. new__Coordinator(int HowManyObjects)
  484. {
  485.     Coordinator    *A_Coordinator;
  486.  
  487.     if ((A_Coordinator = (Coordinator *) malloc(sizeof(Coordinator))) == NULL) {
  488.         printf("problem..\n");
  489.         exit(0);
  490.     };
  491.  
  492.     A_Coordinator->NumberOfObjects = HowManyObjects;
  493.     A_Coordinator->AllStopped = NO;
  494.     A_Coordinator->ObjectCounter = -1;
  495.     A_Coordinator->Counter = 0;
  496.  
  497.  
  498.     A_Coordinator->AllowableDmax = 2.000000;
  499.     A_Coordinator->GetGameType = Coordinator__GetGameType;
  500.     A_Coordinator->UpDateObjectsInitials = Coordinator__UpDateObjectsInitials;
  501.     A_Coordinator->GetTime = Coordinator__GetTime;
  502.     A_Coordinator->OpenSpaceForObjects = Coordinator__OpenSpaceForObjects;
  503.     A_Coordinator->RegisterThisObject = Coordinator__RegisterThisObject;
  504.     A_Coordinator->CheckInitialLocations = Coordinator__CheckInitialLocations;
  505.     A_Coordinator->AdvanceOneStep = Coordinator__AdvanceOneStep;
  506.     A_Coordinator->StartAction = Coordinator__StartAction;
  507.     A_Coordinator->GetBoundary = Coordinator__GetBoundary;
  508.     A_Coordinator->CheckSpeedsAndCalculateK = Coordinator__CheckSpeedsAndCalculateK;
  509.     A_Coordinator->CheckObjectsForTheSpace = Coordinator__CheckObjectsForTheSpace;
  510.     A_Coordinator->ShowObjects = Coordinator__ShowObjects;
  511.     A_Coordinator->AllowableBump = Coordinator__AllowableBump;
  512.     A_Coordinator->ArrangeBalls = Coordinator__ArrangeBalls;
  513.     A_Coordinator->ShowStaticPosition = Coordinator__ShowStaticPosition;
  514.     A_Coordinator->HideStaticPosition = Coordinator__HideStaticPosition;
  515.     A_Coordinator->DrawPockets = Coordinator__DrawPockets;
  516.     A_Coordinator->CheckCondition = Coordinator__CheckPockets;
  517.     A_Coordinator->StillMoving = Coordinator__StillMoving;
  518.     A_Coordinator->InitConfig = Coordinator__InitConfig;
  519.  
  520.  
  521.     return (A_Coordinator);
  522.  
  523. };
  524.