Thursday, August 23, 2018

Galactic Trade C source

One of the first programs I wrote for the VZ200.  It's a port of an old BASIC game to C.
The original was pretty much spaghetti code and it had some undetected bugs.
Translating it to C involved a bit of reworking the logic.
This sort of works, but I didn't have a C compiler that supported floating point at the time to duplicate the original functionality exactly.

The original game itself is sort of a spin on the Hammurabi games.



/*************************************************
* GalacticTrade.c
*************************************************
* Conversion from BASIC by James Diffendaffer
* Copyright (c) Nov 19, 2003, 2005
* This program is freely distributable.
*
* Version 0.8.3 June 8, 2005
*
* Change log:
* Added check for no banks. 6/8/2005
* Print money and parts for building
* Print money for purchasing
* Print unallocated workers for allocate
* some game logic fixes
*************************************************/
#include <math.h>
#include <stdio.h>
#include <stdlib.h> /* rand function */
#include <time.h> /* time function */

#define pokeb(a,b) *((char *)a)=b
#define peekb(a) *((char *)a)

#ifdef VZ
#define video 0x7000 /* define the base address for the screen here */
#define scrsize 32 * 16 /* define the screensize here */
#endif
#pragma -smartpf

int year;
int mineprice, facprice, oreprice, bankprice, siloprice, contprice;
float happy;
int cash, account, loan;
int mines, people, ore;
int facs, banks, silos, conts, parts;
int unalloc, facworkers, mineworkers, oretotal, choice;
int foodbuy;
int prod, partstor, orestor;

/*********************************************************************
* wait_key()
*********************************************************************
*
* line 344
*********************************************************************/

void wait_key(void)
{
 // 344 IF INKEY$ = "" THEN GOTO 344
 #asm
 waitk:
  call 002BH ;scan keyboard once
  or a   ;any key pressed ?
  jr z,waitk  ;back if not
 #endasm
}


/*********************************************************************
* get_key()
*********************************************************************
*
*********************************************************************/
char get_key(void)
{
 #asm
 scan:
  call 002BH ;scan keyboard once
  or a   ;any key pressed ?
  jr z,scan  ;back if not
  ld c,a   ;copy it

 scan1:
  call 002BH ;scan keyboard once
  or a   ;any key pressed ?
  jr nz,scan1 ;back if so
  ld a,c
 /* cp 0DH   ;was it RETURN key ?
  jr NZ,scan  ;back if not
  ;otherwise continue
 */
 #endasm
}

/*********************************************************************
* input()
*********************************************************************
*
* line 38
*********************************************************************/
int input(char *string)
{
 int num = 0;
 char numstrng[10]; /* buffer to build the number string */
 int i = 0;   /*index into numstrng */

 printf("%s", string);
 /* get an integer value here one char at a time */
 do {
   num = (int)getkey();
   if((num >= '0') && (num <= '9') && (i < 10))
   {
    printf("%d", num - '0');
    numstrng[i++] = num;
   }
   else if(num == 0x0d)
   {
    numstrng[i] = 0;
    printf("\n");
   } /*backspace*/ /*else if(val == BS) { i--; }*/
 } while (num != 0x0d); /* until RETURN */
 num = atoi(numstrng);
 return num;
}


/*********************************************************************
* rnd()
*********************************************************************
* Generate a random number between 0 and 1 if passed 0
* If range is greater than 0, 0 <= random <= range.
*********************************************************************/
double rnd(int range)
{
 double val;
 double RND_MAX = (double)RAND_MAX;

 if(range == 0)
 {
  val = ( (double)rand() / (RND_MAX+(double)1.00) );
 }
 else
 {
  val = rand(range); /* only valid if range <= RAND_MAX */
 }
 return val;
}


/*********************************************************************
* cls()
*********************************************************************
* Clear the screen
*********************************************************************/
void cls(void)
{
 #asm
  call 01C9H /*clear screen, home cursor etc.*/
 #endasm
 /*memset(video, 0, scrsize); */
 /*set cursor position to top left corner */
}



/*********************************************************************
* buy()
*********************************************************************
*
* line 38
*********************************************************************/
void buy(void)
{
 int choice, foodbuy, minebuy, bankbuy, facbuy, orebuy, silobuy, contbuy;

 choice = foodbuy = minebuy = bankbuy = facbuy = orebuy = silobuy = contbuy = 0;

 do
 {
  choice = 0;
  do
  {
   cls();
   printf("Buying:\n");
   printf("What do you want to do?\n");
   printf("1 - Buy food\n");
   printf("2 - Buy mines\n");
   printf("3 - Buy factories\n");
   printf("4 - Buy ore\n");
   printf("5 - Buy banks\n");
   printf("6 - Buy ore silos\n");
   printf("7 - Buy part containers\n");
   printf("8 - Go back to main menu\n");
   choice = input("Your choice: ");
  } while((choice < 1) || (choice > 8));

  cls();
  printf("You have $%d", cash);
  switch(choice)
  {
   case 1: /* buy food */
    do {
     printf(" and %d mouths to feed.\n", people);
     foodbuy = input("How much to spend on food: ");
    } while((foodbuy < 0) || (foodbuy > cash));
    cash -= foodbuy;
    break;

   case 2: /* buy mines */
    do
    {
     printf(" and %d mines.\nEach mine costs about $%d.\n", mines, mineprice);
     minebuy = input("How many mines do you wish to buy? ");
    } while((minebuy < 0) || ((minebuy * mineprice) > cash));
    mines += minebuy;
    cash -= (minebuy * mineprice);
    break;

   case 3: /* buy factories */
    do
    {
     printf(" and %d factories.\nOne factory costs $%d.\n", facs,facprice);
     facbuy = input("How many factories do you wish to buy? ");
    } while((facbuy < 0) || ((facbuy * facprice) > cash));
    facs += facbuy;
    cash -= (facbuy * facprice);
    break;

   case 4: /* buy ore */
    do
    {
     printf(".\nCurrent ore price: $%d\n", oreprice);
     orebuy = input("How many tons do you wish to buy? ");
    } while((orebuy < 0) || ((orebuy * oreprice) > cash));
    oretotal += orebuy;
    cash -= (orebuy * oreprice);
    break;

   case 5: /* buy banks */
    do
    {
     printf(".\nA bank will cost: $%d\n", bankprice);
     bankbuy = input("How many do you wish to buy? ");
    } while((bankbuy < 0) || ((bankbuy * bankprice) > cash));
    banks += bankbuy;
    cash -= (bankbuy * bankprice);
    break;

   case 6: /* buy ore silos */
    do
    {
     printf(".\nEach ore silo is priced at: $%d\n", siloprice);
     silobuy = input("How many do you wish to buy? ");
    } while((silobuy < 0) || ((silobuy * siloprice) > cash));
    silos += silobuy;
    cash -= (silobuy * siloprice);
    break;

   case 7: /* buy part containers */
    do
    {
     printf(".\nEach part container is priced at: $%d\n", contprice);
     contbuy = input("How many do you wish to buy? ");
    } while ((contbuy < 0) || ((contbuy * contprice) > cash));
    conts += contbuy;
    cash -= contbuy * contprice;
    // break;
    //case 8: /* go back to main menu */
    // break;
  }
 } while(choice != 8);
 return;
}


/*********************************************************************
* sell()
*********************************************************************
*
*
*********************************************************************/
void sell(void)
{
 int choice;
 int minesell, banksell, facsell, oresell, silosell, contsell, partsell;

 do
 {
  cls();
  printf("Selling:\n");
  printf("What do you want to do?\n");
  printf("1 - Sell ore.\n");
  printf("2 - Sell mines.\n");
  printf("3 - Sell parts.\n");
  printf("4 - Sell factories.\n");
  printf("5 - Sell banks.\n");
  printf("6 - Sell ore silos.\n");
  printf("7 - Sell part containers.\n");
  printf("8 - Go back to main menu.\n\n");
  choice = input("Your choice: ");

  switch(choice)
  {
   case 1: /* sell ore */
    do
    {
     cls();
     printf("You have %d tons of ore, and each ton will sell for $%d.\n", oretotal, oreprice);
     oresell = input("How many tons of ore do you wish to sell? ");
    } while((oresell < 0) || (oresell > oretotal));
    cash += (oresell * oreprice);
    oretotal -= oresell;
    break;

   case 2: /* sell mines */
    do
    {
     cls();
     printf("You have %d mines, and each will sell for $%d\n", mines, mineprice);
     minesell = input("How many mines do you wish to sell? ");
    } while((minesell < 0) || (minesell > mines));
    if(minesell == mines) {
     printf("You can't sell ALL your mines! Selling all but one instead...\n");
     minesell--;
    }
    mines -= minesell;
    cash += (minesell * mineprice);
    break;

   case 3: /* sell parts */
    do
    {
     cls();
     printf("%d parts have so far been produced in your factories.\n", parts);
     partsell = input("How many do you wish to sell? ");
    } while((parts - partsell) < 0);
    parts -= partsell;
    cash += oreprice * 5.0 * 1.5 * partsell;
    break;

   case 4: /* sell factories */
    do
    {
     cls();
     printf("You have %d factories in your colony.\n", facs);
     facsell = input("How many do you wish to sell? ");
    } while((facs - facsell) <= 0);
    facs -= facsell;
    cash += (facprice * facsell);
    break;

   case 5: /* sell banks */
    do
    {
     cls();
     printf("You have %d banks in your colony.\n", banks);
     banksell = input("How many do you wish to sell? ");
    } while((banks - banksell) <= 0);
    banks -= banksell;
    cash += (bankprice * banksell);
    break;

   case 6: /* sell ore silos */
    do
    {
     cls();
     printf("You have %d ore silos in your colony.\n", silos);
     silosell = input("How many do you wish to sell? ");
    } while((silos - silosell) <= 0);
    silos -= silosell;
    cash += (siloprice * silosell);
    break;

   case 7: /* sell part containers */
    do
    {
     cls();
     printf("You have %d part containers in your colony.\n", conts);
     contsell = input("How many do you wish to sell? ");
    } while((conts - contsell) <= 0);
    conts -= contsell;
    cash += (contprice * contsell);
    break;

   case 8: /* return */
    break;
  }
 } while(choice != 8);
 return;
}



/*********************************************************************
* allocate()
*********************************************************************
*
* 
*********************************************************************/
void allocate(void)
{
 int deallnum, mwadd;
 cls();
 printf("There is a total of %d workers in the colony.\n", people);
 printf("%d workers are currently allocated to your mines, and %d are currently allocated to your factories.\n", mineworkers, facworkers);
 printf("This leaves you with %d unallocated workers.\n", unalloc);
 printf("What do you want to do?\n");
 printf("1 - Allocate\n");
 printf("2 - Deallocate\n");
 printf("3 - Go back to main menu\n\n");
 choice = input("Your choice: ");

 switch(choice) 
 {
  case 1: /* 176 */
  {
   do
   {
    cls();
    if(unalloc == 0)
    {
     printf("You have no workers to allocate, deallocate some first.\n");
     wait_key();
     return;
    }

    if(facs == 0)
    {
     printf("Since you have no factories yet, all your unallocated workers will have to go to the mines.\n");
     mineworkers += unalloc;
     unalloc = 0;
     wait_key();
     return;
    }
    printf("There are %d unallocated workers.\n", unalloc);
    deallnum = input("Allocate how many? ");
   } while(deallnum > unalloc);
   unalloc -= deallnum;

   cls();
   printf("There are %d unallocated workers.\n", unalloc);
   printf("Where will the workers go?\n");
   printf("1 - Mines\n");
   printf("2 - Factories\n");
   choice = input("Your choice: "); 

   switch(choice) 
   {
    case 1:
     mineworkers += deallnum;
     break;

    case 2:
     facworkers += deallnum;
     /****** what did I screw up here? ********/
     unalloc += deallnum;
     //return;

     mwadd = input("How many workers should be added to the mines staff? ");
     mineworkers += mwadd;
     unalloc -= mwadd; 
     facworkers += unalloc;
     printf("The remaining people will work in your factories then.\n");
     unalloc = 0;
     wait_key();
     return;
     //break;
   }
  }
  case 2: /* 199 */
  {
   do
   {
    cls();
    printf("%d workers are currently allocated to your mines, and %d are currently allocated to your factories.\n", mineworkers, facworkers);
    printf("Deallocate from where?\n");
    printf("1 - Mines\n");
    printf("2 - Factories\n");
    choice = input("Your choice: ");
    deallnum = input("Deallocate how many? ");
   } while((choice < 1) || (choice > 2));

   switch(choice)
   {
    case 1:
     if(deallnum > mineworkers)
     {
      printf("You dont have that many workers, deallocating all instead.\n");
      deallnum = mineworkers;
     }
     mineworkers -= deallnum;
     break;
    case 2:
     if(deallnum > facworkers)
     {
      printf("You dont have that many workers, deallocating all instead.\n");
      deallnum = facworkers;
     }
     facworkers -= deallnum;
     break;
   }

   unalloc += deallnum;
   return;
  }
  case 3:
  {
   choice = 0;
   return;//CHOICE = 0: RETURN
   //175 GOTO 163
  }
 }
}



/*********************************************************************
* build()
*********************************************************************
*
* line 210
*********************************************************************/
void build(void)
{
 cls();
 printf("So far, you have accumulated a total of %d parts.\n", parts);
 printf("You also have $%d.\n", cash);
 printf("What do you wish to build?\n");
 printf("1 - Mine.\n");
 printf("2 - Factory.\n");
 printf("3 - Bank.\n");
 printf("4 - Silo.\n");
 printf("5 - Container.\n");
 printf("6 - Nothing, I want to return to the main menu.\n");
 choice = input("Your choice: ");

 cls();
 printf("You have $%d and %d parts.\n", cash, parts);
 switch(choice)
 {
  case 1:
   printf("Building a mine will require $%d and 100 parts.\n", (mineprice / 2.0) );
   if(parts < 100) printf("Not enough parts.\n");
   if(cash < (mineprice / 2.0)) printf("Not enough money.\n");
   if((parts > 100) && (cash > (mineprice / 2.0)))
   {
    mines++;
    parts -= 100;
    cash -= (mineprice / 2.0);
   }
   break; //RETURN

  case 2:
   printf("Building a factory will require $%d and 200 parts.\n", (facprice / 2.0));
   if(parts < 200) printf("Not enough parts.\n");
   if(cash < (facprice / 2.0)) printf("Not enough money.\n");
   if((parts > 200) && (cash > (facprice / 2.0)))
   {
    facs++;
    parts -= 200;
    cash -= (facprice / 2.0);
   }
   break; //RETURN

  case 3:
   printf("Building a bank will require $%d and 300 parts.\n", (bankprice / 2.0));
   if(parts < 300) printf("Not enough parts.\n");
   if(cash < (bankprice / 2.0)) printf("Not enough money.\n");
   if( (parts > 300) && (cash > (bankprice / 2.0)))
   {
    banks++;
    parts -= 300;
    cash -= (bankprice /2.0);
   }
   break; //RETURN

  case 4:
   printf("Building an ore silo will require $%d and 300 parts.\n", (siloprice / 2.0));
   if(parts < 300) printf("Not enough parts.\n");
   if(cash < (siloprice / 2.0)) printf("Not enough money.\n");
   if((parts > 300) && (cash > (siloprice / 2.0)))
   {
    silos++;
    parts -= 300;
    cash -= (siloprice / 2.0);
   }
   break; //RETURN

  case 5:
   printf("Building a part container will require $%d and 300 parts.\n", (contprice / 2.0));
   if(parts < 300) printf("Not enough parts.\n");
   if(cash < (contprice / 2.0)) printf("Not enough money.\n");
   if((parts > 300) && (cash > (contprice / 2.0)))
   {
    conts++;
    parts -= 300;
    cash -= (contprice / 2.0);
   }
   break; //RETURN

  case 6:
   choice = 0;
   //RETURN
 }
 if(choice != 6) wait_key();
 //226 GOTO 210
}



/*********************************************************************
* bank()
*********************************************************************
*
*********************************************************************/
void bank(void)
{
 int deposit;

 cls();
 if(banks > 0)
 {
  printf("Welcome to our establishment, Sir!\n");
  printf("Our interest rate is %d%%\n", banks * 5);
  printf("1 - Deposit.\n");
  printf("2 - Withdraw.\n");
  printf("3 - Borrow money.\n");
  printf("4 - Pay off debt.\n");
  printf("5 - Return to main menu.\n");
  choice = input("What will it be today? ");

  switch(choice)
  {
   case 1:
    do
    {
     cls();
     printf("Your account currently has $%d deposited.\n", account);
     deposit = input("How much would you like to add? ");
    } while (deposit > cash);
    cash -= deposit;
    account += deposit;
    break;

   case 2:
    do
    {
     cls();
     printf("Your account currently has $%d deposited.\n", account);
     deposit = input("How much would you like to take? ");
    } while (deposit > account);
    cash += deposit;
    account -= deposit;
    break;

   case 3:
    do
    {
     cls();
     if(loan != 0) printf("Your current loan is $%d.\n", loan);
     printf("You can take out a loan of up to $%d.\n", banks * 10000 - loan);
     deposit = input("How much will you borrow? ");
    } while (deposit > (banks * 10000 - loan));
    cash += deposit;
    loan += deposit;
    break;

   case 4:
    do
    {
     cls();
     printf("Your debt with us is $%d.\n", loan);
     deposit = input("How much will you pay us back? ");
    } while ((deposit > cash) || (deposit < 0));
    if(deposit > loan) deposit = loan;
    cash -= deposit;
    loan -= deposit;
    break;

   case 5:
    choice = 0;
  }
 }
 else
 {
  printf("You have no banks!\n");
  wait_key();
 }
 //266 GOTO 252
}




/*********************************************************************
* main()
*********************************************************************
*
*********************************************************************/
int main()
{
 int a, pplchange;
 double happychg;
 char *seed = 0x7890;
 /* srand(time(0));*/ /* seed the random number generator */
 srand(*seed + *seed+1 + *seed+2); /* I have no idea if this actually works */

 banks = 0;
 mines = 3;
 people = (int)(rnd(0) * 10.0 + 41.0);
 cash = (int)((rnd(0) * 50.0 + 50.0) * (double)people);
 ore = (int)(rnd(0) * 25.0 + 50.0);
 year = 1;
 happy = 1.0;

 /* start loop here? */
 //10 GOSUB 315
 do
 {
  /* line 315 */
  mineprice = (int)(rnd(0) * 2000.0 + 2000.0);
  facprice = (int)(rnd(0) * 2000.0 + 7000.0);
  bankprice = (int)(rnd(0) * 7000.0 + 7000.0);
  siloprice = (int)(rnd(0) * 3000.0 + 3000.0);
  contprice = (int)(rnd(0) * 3000.0 + 3000.0);
  oreprice = (int)(rnd(0) * 15.0 + 15.0);
  oretotal = oretotal + ore * mines;
  foodbuy = 0;
  orestor = mines * 75 + silos * 100;

  cls();
  printf("Year:%d\n\n", year);
  unalloc = people - facworkers - mineworkers;
  printf("There are %d workers in the colony.\n", people);
  printf("%d of those workers are not allocated to any job.\n", unalloc);
  printf("You have %d mines and $%d\n", mines, cash);
  printf("Satisfaction factor:%d%%\n", (int)(happy * 50.0));
  printf("Your mines produced %d tons of ore each.\n", ore);
  printf("Ore in store=%d Tons\n\n", oretotal);
  wait_key();
 do
 {
  cls();
  printf("What do you want to do now?\n");
  printf("1 - Buy.\n");
  printf("2 - Sell.\n");
  printf("3 - Allocate workers.\n");
  printf("4 - Build.\n");
  printf("5 - Visit the local bank.\n");
  printf("6 - End this turn.\n\n");

  choice = input("Your choice: ");

  switch(choice)
  {
   case 1: /* buy */
    buy();
    break;

   case 2: /* sell */
    sell();
    break;

   case 3: /* allocate workers */
    allocate();
    break;

   case 4: /* build */
    build();
    break;

   case 5: /* visit the local bank */
    bank();
    break;

   case 6: /* end this turn */
    //GOSUB 293
    break;
  }
 } while (choice != 6);
 //RETURN

 /* () end of turn line 293*/

 happychg = ((foodbuy / people) - 100.0) / 100.0;
 if(foodbuy / people > 120) happychg = .1;
 if(foodbuy / people < 60) happychg = -.2;
 if(happy < 2.1) happy += happychg;
 account += account * (banks / 100.0) * 5.0;
 loan += loan * (banks / 100.0) * 5.0;
 for(a = 0; a <= facworkers; a++)
 {
  if(oretotal > 4) oretotal -= 5;
  if(oretotal > 4) prod++;
 }

 parts += (prod * (facs / 2.0) * happy);
 partstor = facs * 50 + conts * 100;
 if(parts > partstor)
 {
  printf("INSUFFICIENT STORAGE CAPACITY!: %d PARTS THROWN AWAY!!\n",
  parts -partstor);
  parts = partstor;
  wait_key();
 }

 if(happy > 1.1) ore += (rnd(0) * 10.0 + 1.0);
 if(happy < .9) ore -= (rnd(0) * 20.0 + 1.0);
 if((people / mines) < 10)
 {
  printf("YOU'VE OVERWORKED EVERYONE!\n");
  wait_key();
  exit(0);
  //GOTO 343
 }
 pplchange = ((happy - 1.0) * (rnd(0) * 10.0 + 10.0));

 people += pplchange;
 if(!((pplchange < 0) & (mineworkers < (0 - pplchange))))
 {
  mineworkers += pplchange;
  people += pplchange;
 }

 if((pplchange < 0) & (mineworkers < (0 - pplchange)))
 {
  facworkers += pplchange;
 }

 if(oretotal > orestor)
 {
  printf("INSUFFICIENT STORAGE CAPACITY!: %d TONS OF ORE THROWN
  AWAY!!\n", oretotal - orestor);
  oretotal = orestor;
  wait_key();
 }

 if(happy < .5)
 {
  printf("THE WORKERS REVOLTED!\n");
  wait_key();
  exit(0);
  //GOTO 343
 }

 if(people < 41)
 {
  printf("NOT ENOUGH PEOPLE LEFT!\n");
  wait_key();
  exit(0);
  //GOTO 343
 }

 if(rnd(0) <= .01)
 {
  printf("RADIOACTIVE LEAK... MANY DIE!\n");
  people /= 2;
  mineworkers /= 2;
  facworkers /= 2;
  wait_key();
 }

 if(ore >= 150) // if ore < 150 RETURN
 {
  printf("MARKET GLUT - PRICE DROPS!\n");
  ore /= 2;
  wait_key();
 }
 year++;
 } while (year < 11);

 printf("YOU'VE SURVIVED YOUR TERM OF OFFICE!\n");
 wait_key();
 //343 END 
}


/***************************
***************************/

No comments:

Post a Comment