2011-07-15 20:43:19 -04:00
|
|
|
/************************************************************************
|
|
|
|
* *
|
|
|
|
* Star Traders: A Game of Interstellar Trading *
|
|
|
|
* Copyright (C) 1990-2011, John Zaitseff *
|
|
|
|
* *
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Author: John Zaitseff <J.Zaitseff@zap.org.au>
|
|
|
|
$Id$
|
|
|
|
|
|
|
|
This file, exch.c, contains the implementation of functions dealing
|
|
|
|
with the Interstellar Stock Exchange and Trading Bank as used in Star
|
|
|
|
Traders.
|
|
|
|
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify it
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
Free Software Foundation, either version 3 of the License, or (at your
|
|
|
|
option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "trader.h"
|
|
|
|
|
|
|
|
|
2011-07-18 06:16:55 -04:00
|
|
|
/************************************************************************
|
2011-07-21 23:05:06 -04:00
|
|
|
* Module-specific function prototypes *
|
2011-07-18 06:16:55 -04:00
|
|
|
************************************************************************/
|
|
|
|
|
2011-07-21 23:05:06 -04:00
|
|
|
/*
|
|
|
|
Function: visit_bank - Visit the Interstellar Trading Bank
|
|
|
|
Parameters: (none)
|
|
|
|
Returns: (nothing)
|
|
|
|
|
|
|
|
This function allows the current player to borrow or repay money from
|
|
|
|
the Interstellar Trading Bank.
|
|
|
|
*/
|
|
|
|
static void visit_bank (void);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Function: trade_shares - Buy and sell shares in a particular company
|
|
|
|
Parameters: num - Company with which to trade
|
|
|
|
bid_used - Has the player used up their bid?
|
|
|
|
Returns: (nothing)
|
|
|
|
|
|
|
|
This function allows the current player to buy and sell shares in
|
|
|
|
company num. The variable *bid_used is set to true if the player tries
|
|
|
|
to bid for more shares to be released by the company (whether or not
|
|
|
|
that bid was successful).
|
|
|
|
*/
|
|
|
|
static void trade_shares (int num, bool *bid_used);
|
2011-07-18 06:16:55 -04:00
|
|
|
|
|
|
|
|
2011-07-15 20:43:19 -04:00
|
|
|
/************************************************************************
|
|
|
|
* Stock Exchange function definitions *
|
|
|
|
************************************************************************/
|
|
|
|
|
2011-07-21 23:05:06 -04:00
|
|
|
// This function is documented in the file "exch.h"
|
2011-07-18 06:16:55 -04:00
|
|
|
|
2011-07-21 23:05:06 -04:00
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
// exchange_stock: Visit the Interstellar Stock Exchange
|
2011-07-18 06:16:55 -04:00
|
|
|
|
2011-07-15 20:43:19 -04:00
|
|
|
void exchange_stock (void)
|
|
|
|
{
|
2011-07-18 06:16:55 -04:00
|
|
|
selection_t selection = SEL_NONE;
|
|
|
|
bool bid_used = false;
|
|
|
|
bool all_off_map;
|
2011-08-16 04:48:56 -04:00
|
|
|
int w, i, line;
|
2011-07-18 06:16:55 -04:00
|
|
|
|
|
|
|
|
|
|
|
if (quit_selected || abort_game || ! player[current_player].in_game) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-07-22 20:16:03 -04:00
|
|
|
newtxwin(17, WIN_COLS, 1, WCENTER, false, 0);
|
2011-08-16 04:48:56 -04:00
|
|
|
w = getmaxx(curwin);
|
2011-07-18 06:16:55 -04:00
|
|
|
|
|
|
|
while (selection != SEL_EXIT) {
|
|
|
|
selection = SEL_NONE;
|
|
|
|
|
|
|
|
// Display (or refresh) the Stock Exchange window
|
2011-08-16 04:48:56 -04:00
|
|
|
wbkgdset(curwin, attr_normal_window);
|
2011-07-18 06:16:55 -04:00
|
|
|
werase(curwin);
|
|
|
|
box(curwin, 0, 0);
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
center(curwin, 1, 0, attr_title, 0, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_(" Interstellar Stock Exchange "));
|
2011-08-16 04:48:56 -04:00
|
|
|
center(curwin, 2, 0, attr_normal, attr_highlight, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("Player: ^{%s^}"), player[current_player].name);
|
2011-07-18 06:16:55 -04:00
|
|
|
|
|
|
|
all_off_map = true;
|
|
|
|
for (i = 0; i < MAX_COMPANIES; i++) {
|
|
|
|
if (company[i].on_map) {
|
|
|
|
all_off_map = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (all_off_map) {
|
2011-08-16 04:48:56 -04:00
|
|
|
center(curwin, 8, 0, attr_normal, attr_highlight, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("No companies on the map"));
|
2011-07-18 06:16:55 -04:00
|
|
|
} else {
|
2011-08-16 04:48:56 -04:00
|
|
|
mvwhline(curwin, 4, 2, ' ' | attr_subtitle, w - 4);
|
|
|
|
mvwhline(curwin, 5, 2, ' ' | attr_subtitle, w - 4);
|
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
left(curwin, 4, 4, attr_subtitle, 0, 0, 2, _("\nCompany"));
|
|
|
|
right(curwin, 4, w - 4, attr_subtitle, 0, 0, 2, _("Shares\nleft"));
|
2011-08-16 04:48:56 -04:00
|
|
|
right(curwin, 4, w - 6 - STOCK_LEFT_COLS, attr_subtitle, 0, 0,
|
2011-08-16 07:03:41 -04:00
|
|
|
2, _("Shares\nissued"));
|
2011-08-16 04:48:56 -04:00
|
|
|
right(curwin, 4, w - 8 - STOCK_LEFT_COLS - STOCK_ISSUED_COLS,
|
2011-08-16 07:03:41 -04:00
|
|
|
attr_subtitle, 0, 0, 2, _("Return\n(%%)"));
|
2011-08-16 04:48:56 -04:00
|
|
|
right(curwin, 4, w - 10 - STOCK_LEFT_COLS - STOCK_ISSUED_COLS
|
|
|
|
- SHARE_RETURN_COLS, attr_subtitle, 0, 0, 2,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("Price per\nshare (%s)"), lconvinfo.currency_symbol);
|
2011-07-18 06:16:55 -04:00
|
|
|
|
|
|
|
for (line = 6, i = 0; i < MAX_COMPANIES; i++) {
|
|
|
|
if (company[i].on_map) {
|
2011-07-20 03:01:25 -04:00
|
|
|
mvwaddch(curwin, line, 2, PRINTABLE_MAP_VAL(COMPANY_TO_MAP(i))
|
2011-07-22 19:47:13 -04:00
|
|
|
| attr_choice);
|
2011-08-16 04:48:56 -04:00
|
|
|
|
|
|
|
left(curwin, line, 4, attr_normal, 0, 0, 1, "%s",
|
|
|
|
company[i].name);
|
|
|
|
|
|
|
|
right(curwin, line, w - 2, attr_normal, 0, 0, 1, "%'ld ",
|
|
|
|
company[i].max_stock - company[i].stock_issued);
|
|
|
|
right(curwin, line, w - 4 - STOCK_LEFT_COLS, attr_normal,
|
|
|
|
0, 0, 1, "%'ld ", company[i].stock_issued);
|
|
|
|
right(curwin, line, w - 6 - STOCK_LEFT_COLS
|
|
|
|
- STOCK_ISSUED_COLS, attr_normal, 0, 0, 1, "%.2f ",
|
|
|
|
company[i].share_return * 100.0);
|
|
|
|
right(curwin, line, w - 8 - STOCK_LEFT_COLS
|
|
|
|
- STOCK_ISSUED_COLS - SHARE_RETURN_COLS, attr_normal,
|
|
|
|
0, 0, 1, " %!N ", company[i].share_price);
|
|
|
|
|
2011-07-18 06:16:55 -04:00
|
|
|
line++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
wrefresh(curwin);
|
|
|
|
|
|
|
|
// Show menu of choices for the player
|
2011-07-22 20:16:03 -04:00
|
|
|
newtxwin(6, WIN_COLS, 18, WCENTER, true, attr_normal_window);
|
2011-07-18 06:16:55 -04:00
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
left(curwin, 3, 2, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("^{<1>^} Display stock portfolio"));
|
2011-08-16 04:48:56 -04:00
|
|
|
left(curwin, 4, 2, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("^{<2>^} Display galaxy map"));
|
2011-08-16 04:48:56 -04:00
|
|
|
left(curwin, 3, getmaxx(curwin) / 2, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("^{<3>^} Visit the Trading Bank"));
|
2011-08-16 04:48:56 -04:00
|
|
|
left(curwin, 4, getmaxx(curwin) / 2, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("^{<4>^} Exit the Stock Exchange"));
|
2011-07-18 06:16:55 -04:00
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
center(curwin, 1, -1, attr_normal, attr_keycode, attr_highlight, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("Enter selection [^[Company letter^]/^{1^}-^{4^}]: "));
|
2011-07-18 06:16:55 -04:00
|
|
|
|
|
|
|
curs_set(CURS_ON);
|
|
|
|
wrefresh(curwin);
|
|
|
|
|
|
|
|
// Get the actual selection made by the player
|
|
|
|
while (selection == SEL_NONE) {
|
|
|
|
int key = toupper(gettxchar(curwin));
|
|
|
|
|
|
|
|
if (IS_COMPANY_KEY(key)) {
|
|
|
|
if (company[KEY_TO_COMPANY(key)].on_map) {
|
|
|
|
selection = KEY_TO_COMPANY(key);
|
|
|
|
} else {
|
|
|
|
beep();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (key) {
|
|
|
|
case '1':
|
|
|
|
curs_set(CURS_OFF);
|
|
|
|
show_status(current_player);
|
|
|
|
curs_set(CURS_ON);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '2':
|
|
|
|
curs_set(CURS_OFF);
|
|
|
|
show_map(true);
|
|
|
|
curs_set(CURS_ON);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '3':
|
|
|
|
selection = SEL_BANK;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '4':
|
|
|
|
case ' ':
|
2011-07-19 05:22:20 -04:00
|
|
|
case KEY_CANCEL:
|
|
|
|
case KEY_EXIT:
|
2011-07-18 21:10:09 -04:00
|
|
|
case KEY_CTRL('C'):
|
|
|
|
case KEY_CTRL('G'):
|
|
|
|
case KEY_CTRL('\\'):
|
2011-07-18 06:16:55 -04:00
|
|
|
selection = SEL_EXIT;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
beep();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
curs_set(CURS_OFF);
|
|
|
|
|
|
|
|
deltxwin(); // "Enter selection" window
|
|
|
|
txrefresh();
|
|
|
|
|
|
|
|
if (selection == SEL_BANK) {
|
|
|
|
// Visit the Interstellar Trading Bank
|
|
|
|
visit_bank();
|
|
|
|
} else if (selection == SEL_EXIT) {
|
|
|
|
// Exit the Stock Exchange: nothing more to do
|
|
|
|
;
|
|
|
|
} else {
|
|
|
|
trade_shares(selection, &bid_used);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
deltxwin(); // "Stock Exchange" window
|
|
|
|
txrefresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-07-21 23:05:06 -04:00
|
|
|
/************************************************************************
|
|
|
|
* Module-specific function prototypes *
|
|
|
|
************************************************************************/
|
2011-07-18 06:16:55 -04:00
|
|
|
|
2011-07-21 23:05:06 -04:00
|
|
|
// These functions are documented at the start of this file
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
// visit_bank: Visit the Interstellar Trading Bank
|
2011-07-18 06:16:55 -04:00
|
|
|
|
|
|
|
void visit_bank (void)
|
|
|
|
{
|
2011-07-18 10:38:06 -04:00
|
|
|
double credit_limit;
|
2011-07-21 23:05:06 -04:00
|
|
|
double val, max;
|
2011-07-18 10:38:06 -04:00
|
|
|
int key;
|
|
|
|
bool done;
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
chtype *chbuf = xmalloc(BUFSIZE * sizeof(chtype));
|
|
|
|
int x, width;
|
2011-07-18 10:38:06 -04:00
|
|
|
|
|
|
|
|
|
|
|
credit_limit = (total_value(current_player) - player[current_player].debt)
|
|
|
|
* CREDIT_LIMIT_RATE;
|
|
|
|
if (credit_limit < 0.0) {
|
|
|
|
credit_limit = 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Show the informational part of the Bank
|
2011-07-22 20:16:03 -04:00
|
|
|
newtxwin(10, WIN_COLS - 4, 5, WCENTER, true, attr_normal_window);
|
2011-07-18 10:38:06 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
center(curwin, 1, 0, attr_title, 0, 0, 1,
|
|
|
|
_(" Interstellar Trading Bank "));
|
2011-08-16 04:48:56 -04:00
|
|
|
|
|
|
|
mkchstr(chbuf, BUFSIZE, attr_normal, 0, 0, 1, getmaxx(curwin) - 4, &width,
|
2011-08-16 07:03:41 -04:00
|
|
|
1, _("Current cash: "));
|
2011-08-16 04:48:56 -04:00
|
|
|
x = (getmaxx(curwin) + width - (BANK_VALUE_COLS + 2)) / 2;
|
2011-07-18 10:38:06 -04:00
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
rightch(curwin, 3, x, chbuf, 1, &width);
|
|
|
|
right(curwin, 3, x + BANK_VALUE_COLS + 2, attr_normal, attr_highlight, 0,
|
|
|
|
1, " ^{%N^} ", player[current_player].cash);
|
2011-07-18 10:38:06 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
right(curwin, 4, x, attr_normal, 0, 0, 1, _("Current debt: "));
|
2011-08-16 04:48:56 -04:00
|
|
|
right(curwin, 4, x + BANK_VALUE_COLS + 2, attr_normal, attr_highlight, 0,
|
|
|
|
1, " ^{%N^} ", player[current_player].debt);
|
2011-07-18 10:38:06 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
right(curwin, 5, x, attr_normal, 0, 0, 1, _("Interest rate: "));
|
2011-08-16 04:48:56 -04:00
|
|
|
right(curwin, 5, x + BANK_VALUE_COLS + 2, attr_normal, attr_highlight, 0,
|
|
|
|
1, " ^{%.2f%%^} ", interest_rate * 100.0);
|
2011-07-18 10:38:06 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
right(curwin, 7, x, attr_highlight, 0, 0, 1, _("Credit limit: "));
|
2011-08-16 04:48:56 -04:00
|
|
|
whline(curwin, ' ' | attr_title, BANK_VALUE_COLS + 2);
|
|
|
|
right(curwin, 7, x + BANK_VALUE_COLS + 2, attr_title, 0, 0, 1,
|
|
|
|
" %N ", credit_limit);
|
2011-07-18 10:38:06 -04:00
|
|
|
|
|
|
|
wrefresh(curwin);
|
|
|
|
|
|
|
|
// Show menu of choices for the player
|
2011-07-22 20:16:03 -04:00
|
|
|
newtxwin(7, WIN_COLS - 4, 15, WCENTER, true, attr_normal_window);
|
2011-07-18 10:38:06 -04:00
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
center(curwin, 3, 0, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("^{<1>^} Borrow money "));
|
2011-08-16 04:48:56 -04:00
|
|
|
center(curwin, 4, 0, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("^{<2>^} Repay debt "));
|
2011-08-16 04:48:56 -04:00
|
|
|
center(curwin, 5, 0, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("^{<3>^} Exit from the Bank"));
|
2011-07-18 10:38:06 -04:00
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
center(curwin, 1, 0, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("Enter selection [^{1^}-^{3^}]: "));
|
2011-07-18 10:38:06 -04:00
|
|
|
|
|
|
|
curs_set(CURS_ON);
|
|
|
|
wrefresh(curwin);
|
|
|
|
|
2011-07-19 00:36:00 -04:00
|
|
|
done = false;
|
|
|
|
while (! done) {
|
2011-07-18 10:38:06 -04:00
|
|
|
key = gettxchar(curwin);
|
|
|
|
|
2011-07-18 21:10:09 -04:00
|
|
|
switch (key) {
|
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '3':
|
2011-07-21 23:05:06 -04:00
|
|
|
wechochar(curwin, key | A_BOLD);
|
|
|
|
done = true;
|
|
|
|
break;
|
|
|
|
|
2011-07-18 21:10:09 -04:00
|
|
|
case ' ':
|
2011-07-19 05:22:20 -04:00
|
|
|
case KEY_CANCEL:
|
|
|
|
case KEY_EXIT:
|
2011-07-18 21:10:09 -04:00
|
|
|
case KEY_CTRL('C'):
|
|
|
|
case KEY_CTRL('G'):
|
|
|
|
case KEY_CTRL('\\'):
|
|
|
|
done = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2011-07-18 10:38:06 -04:00
|
|
|
beep();
|
|
|
|
}
|
2011-07-19 00:36:00 -04:00
|
|
|
}
|
2011-07-18 10:38:06 -04:00
|
|
|
|
|
|
|
curs_set(CURS_OFF);
|
|
|
|
|
|
|
|
switch (key) {
|
|
|
|
case '1':
|
|
|
|
// Borrow money from the Bank
|
|
|
|
if (credit_limit == 0.0) {
|
2011-08-12 04:24:35 -04:00
|
|
|
txdlgbox(MAX_DLG_LINES, 50, 8, WCENTER, attr_error_window,
|
|
|
|
attr_error_title, attr_error_highlight, 0, 0,
|
2011-08-16 07:03:41 -04:00
|
|
|
attr_error_waitforkey, _(" Insufficient Credit Limit "),
|
|
|
|
_("The Bank will not lend you any more money."));
|
2011-07-18 10:38:06 -04:00
|
|
|
} else {
|
2011-08-16 04:48:56 -04:00
|
|
|
chtype *chbuf_cursym;
|
|
|
|
int width_cursym;
|
|
|
|
int n, ret;
|
2011-07-18 10:38:06 -04:00
|
|
|
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
wbkgdset(curwin, attr_normal_window);
|
2011-07-18 10:38:06 -04:00
|
|
|
werase(curwin);
|
|
|
|
box(curwin, 0, 0);
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
n = (lconvinfo.p_sep_by_space == 1) ? 1 : 0;
|
|
|
|
|
|
|
|
mkchstr(chbuf, BUFSIZE, attr_normal, attr_normal | A_BOLD, 0, 1,
|
|
|
|
getmaxx(curwin) / 2, &width_cursym, 1, "^{%s^}",
|
|
|
|
lconvinfo.currency_symbol);
|
|
|
|
chbuf_cursym = chstrdup(chbuf, BUFSIZE);
|
|
|
|
|
|
|
|
mkchstr(chbuf, BUFSIZE, attr_normal, 0, 0, 1, getmaxx(curwin)
|
|
|
|
- BANK_INPUT_COLS - width_cursym - 6, &width, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("How much do you wish to borrow? "));
|
2011-08-16 04:48:56 -04:00
|
|
|
x = (getmaxx(curwin) + width - BANK_INPUT_COLS - width_cursym
|
|
|
|
- n) / 2;
|
|
|
|
rightch(curwin, 3, x, chbuf, 1, &width);
|
2011-07-18 10:38:06 -04:00
|
|
|
|
2011-07-21 23:05:06 -04:00
|
|
|
// Show the currency symbol before or after the input field
|
2011-07-21 20:23:58 -04:00
|
|
|
if (lconvinfo.p_cs_precedes == 1) {
|
2011-08-16 04:48:56 -04:00
|
|
|
leftch(curwin, 3, x, chbuf_cursym, 1, &width_cursym);
|
|
|
|
x += width_cursym + n;
|
2011-07-18 10:38:06 -04:00
|
|
|
} else {
|
2011-08-16 04:48:56 -04:00
|
|
|
leftch(curwin, 3, x + BANK_INPUT_COLS + n, chbuf_cursym, 1,
|
|
|
|
&width_cursym);
|
2011-07-18 10:38:06 -04:00
|
|
|
}
|
|
|
|
|
2011-07-19 01:04:39 -04:00
|
|
|
ret = gettxdouble(curwin, &val, 0.0, credit_limit + ROUNDING_AMOUNT,
|
2011-08-16 04:48:56 -04:00
|
|
|
0.0, credit_limit, 3, x, BANK_INPUT_COLS,
|
2011-07-22 19:47:13 -04:00
|
|
|
attr_input_field);
|
2011-07-18 10:38:06 -04:00
|
|
|
|
2011-07-19 00:21:32 -04:00
|
|
|
if (ret == OK && val > ROUNDING_AMOUNT) {
|
2011-07-18 10:38:06 -04:00
|
|
|
player[current_player].cash += val;
|
|
|
|
player[current_player].debt += val * (interest_rate + 1.0);
|
|
|
|
}
|
2011-08-16 04:48:56 -04:00
|
|
|
|
|
|
|
free(chbuf_cursym);
|
2011-07-18 10:38:06 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '2':
|
|
|
|
// Repay a debt
|
|
|
|
if (player[current_player].debt == 0.0) {
|
2011-08-12 04:24:35 -04:00
|
|
|
txdlgbox(MAX_DLG_LINES, 50, 8, WCENTER, attr_error_window,
|
|
|
|
attr_error_title, attr_error_highlight, 0, 0,
|
2011-08-16 07:03:41 -04:00
|
|
|
attr_error_waitforkey, _(" No Debt "),
|
|
|
|
_("You have no debt to repay."));
|
2011-07-18 10:38:06 -04:00
|
|
|
} else if (player[current_player].cash == 0.0) {
|
2011-08-12 04:24:35 -04:00
|
|
|
txdlgbox(MAX_DLG_LINES, 50, 8, WCENTER, attr_error_window,
|
|
|
|
attr_error_title, attr_error_highlight, 0, 0,
|
2011-08-16 07:03:41 -04:00
|
|
|
attr_error_waitforkey, _(" No Cash "),
|
|
|
|
_("You have no cash with which to repay the debt!"));
|
2011-07-18 10:38:06 -04:00
|
|
|
} else {
|
2011-08-16 04:48:56 -04:00
|
|
|
chtype *chbuf_cursym;
|
|
|
|
int width_cursym;
|
|
|
|
int n, ret;
|
2011-07-18 10:38:06 -04:00
|
|
|
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
wbkgdset(curwin, attr_normal_window);
|
2011-07-18 10:38:06 -04:00
|
|
|
werase(curwin);
|
|
|
|
box(curwin, 0, 0);
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
n = (lconvinfo.p_sep_by_space == 1) ? 1 : 0;
|
|
|
|
|
|
|
|
mkchstr(chbuf, BUFSIZE, attr_normal, attr_normal | A_BOLD, 0, 1,
|
|
|
|
getmaxx(curwin) / 2, &width_cursym, 1, "^{%s^}",
|
|
|
|
lconvinfo.currency_symbol);
|
|
|
|
chbuf_cursym = chstrdup(chbuf, BUFSIZE);
|
|
|
|
|
|
|
|
mkchstr(chbuf, BUFSIZE, attr_normal, 0, 0, 1, getmaxx(curwin)
|
|
|
|
- BANK_INPUT_COLS - width_cursym - 6, &width, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("How much do you wish to repay? "));
|
2011-08-16 04:48:56 -04:00
|
|
|
x = (getmaxx(curwin) + width - BANK_INPUT_COLS - width_cursym
|
|
|
|
- n) / 2;
|
|
|
|
rightch(curwin, 3, x, chbuf, 1, &width);
|
2011-07-18 10:38:06 -04:00
|
|
|
|
2011-07-21 23:05:06 -04:00
|
|
|
// Show the currency symbol before or after the input field
|
2011-07-21 20:23:58 -04:00
|
|
|
if (lconvinfo.p_cs_precedes == 1) {
|
2011-08-16 04:48:56 -04:00
|
|
|
leftch(curwin, 3, x, chbuf_cursym, 1, &width_cursym);
|
|
|
|
x += width_cursym + n;
|
2011-07-18 10:38:06 -04:00
|
|
|
} else {
|
2011-08-16 04:48:56 -04:00
|
|
|
leftch(curwin, 3, x + BANK_INPUT_COLS + n, chbuf_cursym, 1,
|
|
|
|
&width_cursym);
|
2011-07-18 10:38:06 -04:00
|
|
|
}
|
|
|
|
|
2011-07-19 00:21:32 -04:00
|
|
|
max = MIN(player[current_player].cash, player[current_player].debt);
|
2011-07-18 10:38:06 -04:00
|
|
|
|
2011-07-19 01:04:39 -04:00
|
|
|
ret = gettxdouble(curwin, &val, 0.0, max + ROUNDING_AMOUNT, 0.0,
|
2011-08-16 04:48:56 -04:00
|
|
|
max, 3, x, BANK_INPUT_COLS, attr_input_field);
|
2011-07-18 10:38:06 -04:00
|
|
|
|
|
|
|
if (ret == OK) {
|
|
|
|
player[current_player].cash -= val;
|
|
|
|
player[current_player].debt -= val;
|
|
|
|
|
|
|
|
if (player[current_player].cash < ROUNDING_AMOUNT) {
|
|
|
|
player[current_player].cash = 0.0;
|
|
|
|
}
|
|
|
|
if (player[current_player].debt < ROUNDING_AMOUNT) {
|
|
|
|
player[current_player].debt = 0.0;
|
|
|
|
}
|
|
|
|
}
|
2011-08-16 04:48:56 -04:00
|
|
|
|
|
|
|
free(chbuf_cursym);
|
2011-07-18 10:38:06 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
deltxwin(); // "Enter selection" window
|
|
|
|
deltxwin(); // Trading Bank window
|
|
|
|
txrefresh();
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
free(chbuf);
|
2011-07-18 06:16:55 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-07-21 23:05:06 -04:00
|
|
|
/***********************************************************************/
|
|
|
|
// trade_shares: Buy and sell shares in a particular company
|
2011-07-18 06:16:55 -04:00
|
|
|
|
|
|
|
void trade_shares (int num, bool *bid_used)
|
|
|
|
{
|
2011-07-19 00:21:32 -04:00
|
|
|
bool done;
|
2011-08-16 04:48:56 -04:00
|
|
|
int key, ret, w, x;
|
2011-07-21 23:05:06 -04:00
|
|
|
long int maxshares, val;
|
2011-07-19 00:21:32 -04:00
|
|
|
double ownership;
|
2011-08-16 04:48:56 -04:00
|
|
|
chtype *chbuf;
|
|
|
|
int width;
|
2011-07-19 00:21:32 -04:00
|
|
|
|
|
|
|
|
2011-07-18 06:16:55 -04:00
|
|
|
assert(num >= 0 && num < MAX_COMPANIES);
|
2011-07-21 23:05:06 -04:00
|
|
|
assert(company[num].on_map);
|
2011-07-18 06:16:55 -04:00
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
chbuf = xmalloc(BUFSIZE * sizeof(chtype));
|
2011-07-19 00:21:32 -04:00
|
|
|
|
|
|
|
ownership = (company[num].stock_issued == 0) ? 0.0 :
|
2011-07-21 23:05:06 -04:00
|
|
|
((double) player[current_player].stock_owned[num]
|
|
|
|
/ company[num].stock_issued);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
|
|
|
// Show the informational part of the trade window
|
2011-07-22 20:16:03 -04:00
|
|
|
newtxwin(9, WIN_COLS - 4, 5, WCENTER, true, attr_normal_window);
|
2011-08-16 04:48:56 -04:00
|
|
|
w = getmaxx(curwin);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
center(curwin, 1, 0, attr_title, 0, 0, 1, _(" Stock Transaction in %s "),
|
2011-07-19 00:21:32 -04:00
|
|
|
company[num].name);
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
mkchstr(chbuf, BUFSIZE, attr_normal, 0, 0, 1, w / 2, &width, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("Shares issued: "));
|
2011-08-16 04:48:56 -04:00
|
|
|
leftch(curwin, 3, 2, chbuf, 1, &width);
|
|
|
|
right(curwin, 3, width + SHARE_PRICE_COLS + 2, attr_normal, attr_highlight,
|
|
|
|
0, 1, "^{%'ld^}", company[num].stock_issued);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
left(curwin, 4, 2, attr_normal, 0, 0, 1, _("Shares left: "));
|
2011-08-16 04:48:56 -04:00
|
|
|
right(curwin, 4, width + SHARE_PRICE_COLS + 2, attr_normal, attr_highlight,
|
|
|
|
0, 1, "^{%'ld^}", company[num].max_stock - company[num].stock_issued);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
left(curwin, 5, 2, attr_normal, 0, 0, 1, _("Price per share: "));
|
2011-08-16 04:48:56 -04:00
|
|
|
right(curwin, 5, width + SHARE_PRICE_COLS + 2, attr_normal, attr_highlight,
|
|
|
|
0, 1, "^{%N^}", company[num].share_price);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
left(curwin, 6, 2, attr_normal, 0, 0, 1, _("Return: "));
|
2011-08-16 04:48:56 -04:00
|
|
|
right(curwin, 6, width + SHARE_PRICE_COLS + 2, attr_normal, attr_highlight,
|
|
|
|
0, 1, "^{%.2f%%^}", company[num].share_return * 100.0);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
left(curwin, 3, w / 2, attr_normal, 0, 0, 1, _("Current holdings: "));
|
2011-08-16 04:48:56 -04:00
|
|
|
right(curwin, 3, w - 2, attr_normal, attr_highlight, 0, 1, " ^{%'ld^} ",
|
|
|
|
player[current_player].stock_owned[num]);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
left(curwin, 4, w / 2, attr_normal, 0, 0, 1, _("Percentage owned: "));
|
2011-08-16 04:48:56 -04:00
|
|
|
right(curwin, 4, w - 2, attr_normal, attr_highlight, 0, 1, " ^{%.2f%%^} ",
|
|
|
|
ownership * 100.0);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
left(curwin, 6, w / 2, attr_highlight, 0, 0, 1, _("Current cash: "));
|
2011-08-16 04:48:56 -04:00
|
|
|
whline(curwin, ' ' | attr_title, TRADE_VALUE_COLS + 2);
|
|
|
|
right(curwin, 6, w - 2, attr_title, 0, 0, 1, " %N ",
|
|
|
|
player[current_player].cash);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
|
|
|
wrefresh(curwin);
|
|
|
|
|
|
|
|
// Show menu of choices for the player
|
2011-07-22 20:16:03 -04:00
|
|
|
newtxwin(7, WIN_COLS - 4, 14, WCENTER, true, attr_normal_window);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
left(curwin, 3, 2, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("^{<1>^} Buy stock from company"));
|
2011-08-16 04:48:56 -04:00
|
|
|
left(curwin, 4, 2, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("^{<2>^} Sell stock back to company"));
|
2011-08-16 04:48:56 -04:00
|
|
|
left(curwin, 3, getmaxx(curwin) / 2, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("^{<3>^} Bid company to issue more shares"));
|
2011-08-16 04:48:56 -04:00
|
|
|
left(curwin, 4, getmaxx(curwin) / 2, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("^{<4>^} Exit to the Stock Exchange"));
|
2011-07-19 00:21:32 -04:00
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
center(curwin, 1, 0, attr_normal, attr_keycode, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("Enter selection [^{1^}-^{4^}]: "));
|
2011-07-19 00:21:32 -04:00
|
|
|
|
|
|
|
curs_set(CURS_ON);
|
|
|
|
wrefresh(curwin);
|
|
|
|
|
2011-07-19 00:36:00 -04:00
|
|
|
done = false;
|
|
|
|
while (! done) {
|
2011-07-19 00:21:32 -04:00
|
|
|
key = gettxchar(curwin);
|
|
|
|
|
|
|
|
switch (key) {
|
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '3':
|
|
|
|
case '4':
|
2011-07-21 23:05:06 -04:00
|
|
|
wechochar(curwin, key | A_BOLD);
|
|
|
|
done = true;
|
|
|
|
break;
|
|
|
|
|
2011-07-19 00:21:32 -04:00
|
|
|
case ' ':
|
2011-07-19 05:22:20 -04:00
|
|
|
case KEY_CANCEL:
|
|
|
|
case KEY_EXIT:
|
2011-07-19 00:21:32 -04:00
|
|
|
case KEY_CTRL('C'):
|
|
|
|
case KEY_CTRL('G'):
|
|
|
|
case KEY_CTRL('\\'):
|
|
|
|
done = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
beep();
|
|
|
|
}
|
2011-07-19 00:36:00 -04:00
|
|
|
}
|
2011-07-19 00:21:32 -04:00
|
|
|
|
|
|
|
curs_set(CURS_OFF);
|
|
|
|
|
|
|
|
switch (key) {
|
|
|
|
case '1':
|
|
|
|
// Buy stock in company
|
|
|
|
maxshares = player[current_player].cash / company[num].share_price;
|
|
|
|
|
|
|
|
if (company[num].max_stock - company[num].stock_issued == 0) {
|
2011-08-12 04:24:35 -04:00
|
|
|
txdlgbox(MAX_DLG_LINES, 50, 8, WCENTER, attr_error_window,
|
|
|
|
attr_error_title, attr_error_highlight, 0, 0,
|
2011-08-16 07:03:41 -04:00
|
|
|
attr_error_waitforkey, _(" No Shares Available "),
|
|
|
|
_("No more shares are available for purchase."));
|
2011-07-19 00:21:32 -04:00
|
|
|
} else if (maxshares <= 0) {
|
2011-08-12 04:24:35 -04:00
|
|
|
txdlgbox(MAX_DLG_LINES, 50, 8, WCENTER, attr_error_window,
|
|
|
|
attr_error_title, attr_error_highlight, 0, 0,
|
2011-08-16 07:03:41 -04:00
|
|
|
attr_error_waitforkey, _(" Insufficient Cash "),
|
|
|
|
_("You do not have enough cash\n"
|
|
|
|
"to purchase additional shares."));
|
2011-07-19 00:21:32 -04:00
|
|
|
} else {
|
|
|
|
maxshares = MIN(maxshares, company[num].max_stock -
|
|
|
|
company[num].stock_issued);
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
wbkgdset(curwin, attr_normal_window);
|
2011-07-19 00:21:32 -04:00
|
|
|
werase(curwin);
|
|
|
|
box(curwin, 0, 0);
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
center(curwin, 2, 0, attr_normal, attr_highlight, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("You can purchase up to ^{%'ld^} shares."), maxshares);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
mkchstr(chbuf, BUFSIZE, attr_normal, 0, 0, 1,
|
|
|
|
getmaxx(curwin) - TRADE_INPUT_COLS - 4, &width, 1,
|
|
|
|
_("How many shares do you wish to purchase? "));
|
2011-08-16 04:48:56 -04:00
|
|
|
x = (getmaxx(curwin) + width - TRADE_INPUT_COLS) / 2;
|
|
|
|
rightch(curwin, 4, x, chbuf, 1, &width);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
|
|
|
ret = gettxlong(curwin, &val, 0, maxshares, 0, maxshares, 4, x,
|
2011-08-16 04:48:56 -04:00
|
|
|
TRADE_INPUT_COLS, attr_input_field);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
|
|
|
if (ret == OK) {
|
|
|
|
player[current_player].cash -= val * company[num].share_price;
|
|
|
|
player[current_player].stock_owned[num] += val;
|
|
|
|
company[num].stock_issued += val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '2':
|
|
|
|
// Sell stock back to company
|
|
|
|
maxshares = player[current_player].stock_owned[num];
|
|
|
|
if (maxshares == 0) {
|
2011-08-12 04:24:35 -04:00
|
|
|
txdlgbox(MAX_DLG_LINES, 50, 8, WCENTER, attr_error_window,
|
|
|
|
attr_error_title, attr_error_highlight, 0, 0,
|
2011-08-16 07:03:41 -04:00
|
|
|
attr_error_waitforkey, _(" No Shares "),
|
|
|
|
_("You do not have any shares to sell."));
|
2011-07-19 00:21:32 -04:00
|
|
|
} else {
|
2011-08-16 04:48:56 -04:00
|
|
|
wbkgdset(curwin, attr_normal_window);
|
2011-07-19 00:21:32 -04:00
|
|
|
werase(curwin);
|
|
|
|
box(curwin, 0, 0);
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
center(curwin, 2, 0, attr_normal, attr_highlight, 0, 1,
|
2011-08-16 07:03:41 -04:00
|
|
|
_("You can sell up to ^{%'ld^} shares."), maxshares);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
2011-08-16 07:03:41 -04:00
|
|
|
mkchstr(chbuf, BUFSIZE, attr_normal, 0, 0, 1,
|
|
|
|
getmaxx(curwin) - TRADE_INPUT_COLS - 4, &width, 1,
|
|
|
|
_("How many shares do you wish to sell? "));
|
2011-08-16 04:48:56 -04:00
|
|
|
x = (getmaxx(curwin) + width - TRADE_INPUT_COLS) / 2;
|
|
|
|
rightch(curwin, 4, x, chbuf, 1, &width);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
|
|
|
ret = gettxlong(curwin, &val, 0, maxshares, 0, maxshares, 4, x,
|
2011-08-16 04:48:56 -04:00
|
|
|
TRADE_INPUT_COLS, attr_input_field);
|
2011-07-19 00:21:32 -04:00
|
|
|
|
|
|
|
if (ret == OK) {
|
|
|
|
company[num].stock_issued -= val;
|
|
|
|
player[current_player].stock_owned[num] -= val;
|
|
|
|
player[current_player].cash += val * company[num].share_price;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '3':
|
|
|
|
// Bid company to issue more shares
|
|
|
|
maxshares = 0;
|
|
|
|
if (! *bid_used && randf() < ownership && randf() < BID_CHANCE) {
|
|
|
|
maxshares = randf() * ownership * MAX_SHARES_BIDDED;
|
|
|
|
company[num].max_stock += maxshares;
|
|
|
|
}
|
|
|
|
|
|
|
|
*bid_used = true;
|
|
|
|
|
|
|
|
if (maxshares == 0) {
|
2011-08-12 04:24:35 -04:00
|
|
|
txdlgbox(MAX_DLG_LINES, 50, 8, WCENTER, attr_error_window,
|
|
|
|
attr_error_title, attr_error_highlight, 0, 0,
|
2011-08-16 07:03:41 -04:00
|
|
|
attr_error_waitforkey, _(" No Shares Issued "),
|
|
|
|
_("%s has refused\nto issue more shares."),
|
2011-08-12 04:24:35 -04:00
|
|
|
company[num].name);
|
2011-07-19 00:21:32 -04:00
|
|
|
} else {
|
2011-08-12 04:24:35 -04:00
|
|
|
txdlgbox(MAX_DLG_LINES, 50, 8, WCENTER, attr_normal_window,
|
|
|
|
attr_title, attr_normal, attr_highlight, 0,
|
2011-08-16 07:03:41 -04:00
|
|
|
attr_waitforkey, _(" Shares Issued "),
|
|
|
|
_("%s has issued\n^{%'ld^} more shares."),
|
2011-08-12 04:24:35 -04:00
|
|
|
company[num].name, maxshares);
|
2011-07-19 00:21:32 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
deltxwin(); // "Enter selection" window
|
|
|
|
deltxwin(); // Stock Transaction window
|
|
|
|
txrefresh();
|
|
|
|
|
2011-08-16 04:48:56 -04:00
|
|
|
free(chbuf);
|
2011-07-15 20:43:19 -04:00
|
|
|
}
|
2011-07-21 23:05:06 -04:00
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************/
|
|
|
|
// End of file
|