📄 klondike.c
字号:
// The stock is clicked. Draw 1 or 3 new cards.
deselect_all();
draw_from_stock();
} else
if (p.x > +95 && p.x < +200 && p.y > +55 && p.y < +151) {
// The topmost of the three drawn cards or the
// single drawn card is clicked.
deselect_all();
for (c=2 ; c>=0 ; c--) {
if (drawnCards[c]) {
if (drawnCards[c] == fromCard - 1) {
break;
} else {
piles[0][(drawnCards[c])].selected = true;
fromCard = drawnCards[c] + 1;
fromPile = 0;
break;
};
};
};
} else
if (p.x > +255 && p.x < +570 && p.y > +55 && p.y < +151) {
// One of the four suite piles is clicked.
cPile = (int) (p.x - 255) / (CARD_WIDTH + 10); // Which pile?
cPile += 8;
c = pilesCount[cPile];
// Move to pile if selected is an ace and pile is empty.
if (cards_get_value(piles[fromPile][fromCard - 1]) == 1 && !piles[cPile][c-1].card) {
if (!fromPile || fromCard == pilesCount[fromPile]) {
toPile = cPile;
move_card();
deselect_all();
};
} else
// Move the selected card to the clicked pile if possible.
if (piles[fromPile][fromCard - 1].card == piles[cPile][c-1].card + 1) {
if (!fromPile || fromCard == pilesCount[fromPile]) {
toPile = cPile;
move_card();
deselect_all();
};
} else
// Deselect all if topmost card in pile is already selected.
if (piles[cPile][c-1].selected) {
deselect_all();
} else
// If nothing else is selected, select the topmost card
// in the pile if it isn't empty or ace.
if (c && cards_get_value(piles[cPile][c-1]) > 1) {
if (!fromCard) {
fromCard = c;
fromPile = cPile;
piles[fromPile][fromCard - 1].selected = true;
};
};
} else
if (p.x > +15 && p.x < +570 && p.y > +160) {
// One of the seven lower piles is clicked.
cPile = (int) (p.x - 15) / (CARD_WIDTH + 10); // Which pile?
cPile ++;
c = pilesCount[cPile];
// Move card to empty pile if it is a King.
if (cards_get_value(piles[fromPile][fromCard-1]) == 13 && c<1) {
toPile = cPile;
move_card();
deselect_all();
} else
// Turn card if not already turned.
if (!piles[cPile][c - 1].showFace) {
piles[cPile][c - 1].showFace = true;
deselect_all();
} else
// Move card to pile if possible.
if (fromCard && piles[cPile][c-1].showFace && (cards_get_value(piles[fromPile][fromCard-1]) == cards_get_value(piles[cPile][c-1]) - 1) && (cards_get_color(piles[fromPile][fromCard-1]) != cards_get_color(piles[cPile][c-1]))) {
toPile = cPile;
move_card();
deselect_all();
} else
// Select card if nothing else is selected.
if (!fromCard && c && piles[cPile][c - 1].showFace) {
c = get_clicked_card(cPile, p.y, 150);
if (c) {
fromCard = c;
fromPile = cPile;
for (cc=fromCard-1 ; cc<=pilesCount[fromPile] ; cc++)
piles[fromPile][cc].selected = true;
};
} else
// Deselect if already selected.
if (piles[cPile][c - 1].selected) {
deselect_all();
} else {
deselect_all();
};
} else {
// Clicked somwhere else, not on a pile.
deselect_all();
};
redraw_vGame(vGame);
clear_event(event);
// Game over?
if (check_if_won() && startedGame) {
msgbox(MW_INFO, MB_OK, "Well done! You did it!\n");
startedGame = FALSE;
isGameOver = TRUE;
winCount++;
};
};
};
if (event->type == EV_MESSAGE) {
switch (event->message) {
case MSG_CLOSE: {
}; break;
case MSG_KLOND_NEW: {
// New game
if (startedGame) lostCount++;
startedGame = FALSE;
isGameOver = FALSE;
init_deck();
init_game();
deselect_all();
redraw_vGame(vGame);
clear_event(event);
}; break;
case MSG_KLOND_SELGAME: {
// Select game
if (init_deck_sel_game()) {
if (startedGame) lostCount++;
startedGame = FALSE;
isGameOver = FALSE;
init_game();
deselect_all();
};
redraw_vGame(vGame);
clear_event(event);
}; break;
case MSG_KLOND_DECK: {
// Select deck
cards_select_deck();
redraw_vGame(vGame);
clear_event(event);
}; break;
case MSG_TAKE_THREE: {
// "Take three cards" cards option
i = menu_get_item_flags(menu, MSG_TAKE_THREE);
if (i & MIF_CHECKOK) {
drawThreeCards = 1;
} else {
drawThreeCards = 0;
};
clear_event(event);
}; break;
case MSG_KLOND_STAT: {
// Show statistics
l_int totGames = lostCount + winCount;
float winPerc = 0;
l_int lostPerc = 0;
if (totGames) {
winPerc = ((float) winCount / totGames) * 100;
lostPerc = 100 - (l_int) winPerc;
};
msgbox(MW_INFO, MB_OK, "Games played: %d\n\nGames won: %d (%d%%)\n\nGames lost: %d (%d%%)", totGames, winCount, (l_int) winPerc, lostCount, lostPerc);
clear_event(event);
}; break;
case MSG_KLOND_STATRES: {
// Reset statistics
l_dword msg = msgbox(MW_INFO, MB_YES|MB_NO, "Are you sure you want to reset the statistics?");
if (msg == MSG_YES) {
winCount = 0;
lostCount = 0;
};
clear_event(event);
}; break;
case MSG_KLOND_HELP: {
// Display help file
open_help("./help/klondike.hlp");
clear_event(event);
}; break;
case MSG_ABOUT: {
// Show "About klondike" message
msgbox(MW_INFO, MB_OK, TEXT_ABOUT);
clear_event(event);
}; break;
case MSG_CARDS_ABOUT: {
// Show "About cards" message
cards_about();
clear_event(event);
}; break;
};
};
};
p_menu create_game_menu(void) {
menu = new_menu(
new_sub_menu("Game", new_menu(
new_menu_item("New game", "", 0, MSG_KLOND_NEW, NULL,
new_menu_item("Select game", "", 0, MSG_KLOND_SELGAME, NULL,
new_menu_line(
new_menu_item("Show statistics", "", 0, MSG_KLOND_STAT, NULL,
new_menu_item("Reset statistics", "", 0, MSG_KLOND_STATRES, NULL,
new_menu_line(
new_menu_item("Exit", "ALT+F4", 0, MSG_CLOSE, NULL,
NULL)))))))),
new_sub_menu("Options", new_menu(
new_menu_check_item("Take three cards", "", drawThreeCards, 0, MSG_TAKE_THREE, NULL,
new_menu_line(
new_menu_item("Select deck", "", 0, MSG_KLOND_DECK, NULL,
NULL)))),
new_sub_menu("Help", new_menu(
new_menu_item("Help", "", 0, MSG_KLOND_HELP, NULL,
new_menu_line(
new_menu_item("About Klondike", "", 0, MSG_ABOUT, NULL,
new_menu_item("About cards.dlx", "", 0, MSG_CARDS_ABOUT, NULL,
NULL))))),
NULL)))
);
return menu;
};
void create_window(void) {
t_rect r, s;
r = rect_assign(10, 10, 595, 445);
winMain = appwin_init(_malloc(sizeof(t_appwin)),
r,
"Klondike",
WF_MINIMIZE|WF_ABOUT,
ap_id, &trans_event);
winMain->icon16 = load_image("bmp/klondike.ico,16");
VIEW(winMain)->align |= TX_ALIGN_CENTER;
OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(winMain));
s = VIEW(winMain)->size_limits(VIEW(winMain));
r = VIEW(winMain)->bounds;
r = rect_assign(r.a.x, r.a.y, r.b.x + 5, r.a.y + s.a.y + 430);
VIEW(winMain)->change_bounds(VIEW(winMain), r);
r = s;
r = rect_assign(r.a.x, r.a.y, r.a.x, r.a.y + 20);
gameMenu = hormenu_init(_malloc(sizeof(t_menuview)), r, create_game_menu());
OBJECT(winMain)->insert(OBJECT(winMain), OBJECT(gameMenu));
r = rect_assign(r.a.x + 4, r.b.y + 6, r.a.x + 582, r.b.y + 404); // 3, 45, 580, 430
vGame = view_init(_malloc(sizeof(t_view)), r);
VIEW(vGame)->draw = &redraw_vGame;
VIEW(vGame)->transparent = TRUE;
OBJECT(vGame)->translate_event = &trans_event;
OBJECT(winMain)->insert(OBJECT(winMain), OBJECT(vGame));
};
app_begin(void) {
if (ap_process == AP_INIT) {
// Read settings from registry
if (!key_exists("software/klondike")) create_key("software", "klondike");
if (!key_exists("software/klondike/lastgame")) {
create_key("software/klondike", "lastgame");
init_deck();
} else {
curGame = get_key_integer("software/klondike/lastgame");
};
if (!key_exists("software/klondike/takethree")) {
create_key("software/klondike", "takethree");
drawThreeCards = 1;
} else {
drawThreeCards = get_key_integer("software/klondike/takethree");
};
if (!key_exists("software/klondike/won")) {
create_key("software/klondike", "won");
winCount = 0;
} else {
winCount = get_key_integer("software/klondike/won");
};
if (!key_exists("software/klondike/lost")) {
create_key("software/klondike", "lost");
lostCount = 0;
} else {
lostCount = get_key_integer("software/klondike/lost");
};
// Start new game using settings
curCard = 52;
fromPile = fromCard = 0;
cards_init_deck(deck);
cards_shuffle_deck_select(deck, curGame);
redraw_win_title();
init_game();
create_window();
redraw_win_title();
} else
if (ap_process == AP_DONE) {
if (startedGame) lostCount++;
// Store settings in registry when exiting
set_key_integer("software/klondike/lastgame", curGame);
set_key_integer("software/klondike/takethree", drawThreeCards);
set_key_integer("software/klondike/won", winCount);
set_key_integer("software/klondike/lost", lostCount);
cards_uninit_deck();
};
} app_end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -