扎金花
来源:互联网 发布:c语言中flag=1 编辑:程序博客网 时间:2024/04/30 21:55
18岁以下少年儿童请自觉远离赌博,18岁以上少年儿童请把赌博游戏转变成健康的休闲游戏,别掺进¥。
这两天弄了一个扎金花,体会到一个问题:软件工程是提高编程工作效率的必由之路。我们意识不到是因为我们现阶段涉及不到太复杂的设计。在必要的时候,还是得饿补一下OOAD,UML这些东西呀
如果知道扎金花怎么玩的可以直接跳过这一段:扎金花是我国广泛流传的一款扑克牌游戏,参与游戏者可为2-6人。游戏采用52张牌(去除大小王),庄家会给每人发三张牌,拿牌之后开始下注。按照“比较规则”决定胜负。下边按大小顺序依次介绍:三张一样的叫“暴子”,同花顺叫“顺金”,同花但不顺叫“金”,对子(大家都知道),普通牌,然后是不同花的235,以上的一级比一级小,如果两个人级别相同,就比较谁的牌面大。不同花235可以管暴子。
这个类图肯定有错误,因为我就没学过UML
如果上来就编什么也不想的话,弯路一定不会少走地。下面是实现。
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
enum Color { diamond = 0, club, heart, spade, joker };
扑克牌作为一个类。一张扑克牌的实例包括2个数据成员Color和iint,通过这两个值来指示唯一的一张扑克。A的int值用14来表示,joker用15,16,这样便于排序工作。
class Card {
private:
Color color;
int number;
public:
void set(Color color, int number) {
this->color = color; this->number = number;
}
Card operator =(const Card &card) {
this->color = card.color; this->number = card.number;
return *this;
}
void put(int x, int y) {
gotoxy(x, y);
switch(color) {
case spade : putch(6); break;
case heart : textcolor(4); putch(3); break;
case club : putch(5); break;
case diamond: textcolor(4); putch(4); break;
case joker :
if(number == 15) { putch('j'); putch('k'); }
else if(number == 16) {
textcolor(4); putch('J'); putch('K'); textcolor(7);
}
return;
}
switch(number) {
case 10: putch('1'); putch('0'); break;
case 11: putch('J'); putch(' '); break;
case 12: putch('Q'); putch(' '); break;
case 13: putch('K'); putch(' '); break;
case 14: putch('A'); putch(' '); break;
default: putch(number+48); putch(' ');
}
textcolor(7);
}
Color getClr() { return color; }
int getNum() { return number; }
};
在这个程序里的一幅扑克牌里的扑克牌,以及参赛选手,我都放在一个vector里,这样可以不关心他们的数量。扩展vector,提供一个sort()函数以对一幅扑克牌进行基数排序:数字是第一关键字,花色是第二关键字。
class vectorx : public vector<Card> {
public:
void sort() {
int i, j;
Card temp;
for(i = 0; i < this->size()-1; i++)
for(j = 0; j < this->size()-1; j++)
if(this->at(j).getNum() <= this->at(j+1).getNum()) {
temp = this->at(j);
this->at(j) = this->at(j+1);
this->at(j+1) = temp;
}
for(i = 0; i < this->size()-1; i++)
for(j = 0; j < this->size()-1; j++)
if(this->at(j).getNum() == this->at(j+1).getNum() &&
this->at(j).getClr() <= this->at(j+1).getClr()) {
temp = this->at(j);
this->at(j) = this->at(j+1);
this->at(j+1) = temp;
}
}
};
每一个玩家Player有以下几个我们需要关心的属性:他的名字name,他手头的牌hand,他手头的筹码数chips。这里浪费时间最长的就是给3张牌打分的函数了,似乎写得不好,没什么扩充性,很死板。
class Player {
private:
string name;
vectorx hand;
int chips;
int x, y;
public:
Player(string name, int chips, int x, int y) {
this->name = name; this->chips = chips;
this->x = x; this->y = y;
}
void get(Card card) { hand.push_back(card); }
//通过get()函数接收扑克牌。
void clear() { while(!hand.empty()) hand.pop_back(); }
//通过clear()函数清空手中的扑克牌。
void hide() {
//这个函数用于显示对手的扑克牌的牌背。
gotoxy(x+16, y+1); printf("$%5d", chips);
vectorx::iterator Iter;
int i = x+4;
for(Iter = hand.begin(); Iter != hand.end(); Iter++) {
gotoxy(i, y+3); printf("%c%c%c", 177, 177, 177); //177就是一个灰色的ASCII码,作为牌背。
i += 6;
}
}
void status() {
//显示完整的状态,包括当前筹码数和手中的三张牌
gotoxy(x+16, y+1); printf("$%5d", chips);
vectorx::iterator Iter;
int i = x+4;
for(Iter = hand.begin(); Iter != hand.end(); Iter++) {
Iter->put(i, y+3); i += 6;
}
}
void frame() {
//用户状态的框架。
gotoxy(x, y);
printf("%c", 218);
for(int i = 0; i < 21; i++) printf("%c", 196);
printf("%c", 183);
gotoxy(x, y+1); printf("%c %c", 179, 186);
gotoxy(x+1, y+1); cout << name;
gotoxy(x, y+2);
printf("%c", 195);
for(int i = 0; i < 21; i++) printf("%c", 196);
printf("%c", 182);
gotoxy(x, y+3); printf("%c [ ] [ ] [ ] %c", 179, 186);
gotoxy(x, y+4);
printf("%c", 212);
for(int i = 0; i < 21; i++) printf("%c", 205);
printf("%c/n", 188);
}
int score() {
//为手中三张牌打分的函数。
vectorx temp;
temp.assign(hand.begin(), hand.end());
temp.sort();
unsigned result;
result = temp[2].getNum() - 1;
result += ((temp[1].getNum()-1) << 4);
result += ((temp[0].getNum()-1) << 8);
//顺子
bool series = (temp[0].getNum()-temp[1].getNum()==1 &&
temp[1].getNum()-temp[2].getNum()==1) ||
(temp[0].getNum()==14 && temp[1].getNum()==3 &&
temp[2].getNum()==2);
//金
bool suit = temp[0].getClr()==temp[1].getClr() &&
temp[1].getClr()==temp[2].getClr();
//暴子(不知道英语怎么说:)
bool elephant = temp[0].getNum()==temp[1].getNum() &&
temp[1].getNum()==temp[2].getNum();
//2,3,5,老鼠吃大象
bool mause = temp[0].getNum()==5 && temp[1].getNum()==3 &&
temp[2].getNum()==2 && !suit;
if(!suit && temp[0].getNum()==temp[1].getNum()) {
result += ((temp[0].getNum()-1) << 12); return result;
}
if(!suit && temp[1].getNum()==temp[2].getNum()) {
result += ((temp[1].getNum()-1) << 12); return result;
}
if(!suit && series) { result += ((temp[0].getNum()-1) << 16); return result; }
if(suit && !series) { result += ((temp[0].getNum()-1) << 20); return result; }
if(suit && series) { result += ((temp[0].getNum()-1) << 24); return result; }
if(elephant) { result += ((temp[0].getNum()-1) << 28); return result; }
if(mause) { return -1; }
return result;
}
int go(int gc) {
//压筹码
chips -= gc;
return gc;
}
void win(int wc) { chips += wc; }
//获胜结账
int getChp() { return chips; }
string getName() { return name; }
};
下边这个类用来随机发生姓名。这个挺有一般性的,以后也会用得到。
class Name {
vector<string> names;
public:
Name() {
names.push_back("Adam");
names.push_back("Ben");
names.push_back("Michael");
names.push_back("Jack");
names.push_back("Philips");
names.push_back("Eve");
names.push_back("Susan");
names.push_back("Jill");
names.push_back("Rose");
names.push_back("Maggie");
}
string nextName() {
int i = ( (double)rand() / (double)RAND_MAX * names.size() );
string ret = names[i];
names.erase(names.begin()+i);
return ret;
}
};
以下是最中心的类。这里完成的是发牌,压注,结算等等工作。
class Playground {
private:
vectorx poker;
vector<Player> players;
int totalgo;
public:
Playground(int numplayer, int chips) {
Player temp("You", chips, 55, 20);
players.push_back(temp);
Name name;
for(int i = 1; i < numplayer; i++) {
Player temp(name.nextName(), chips, 1, i*5-4);
players.push_back(temp);
}
clrscr();
vector<Player>::iterator Iter = players.begin();
for(; Iter != players.end(); Iter++)
Iter->frame();
}
void reshuffle() {
//洗牌,就是重新建立一幅按顺序排列的扑克牌,把各位手中的牌清空。
while(!poker.empty()) poker.pop_back();
Card card;
for(int i = 0; i < 4; i++)
for(int j = 2; j <= 14; j++) {
card.set(i, j);
poker.push_back(card);
}
//card.set(joker, 15); poker.push_back(card);
//card.set(joker, 16); poker.push_back(card);
//注释掉的这两行是Jokers,在扎金花中用不到。
vector<Player>::iterator Iter = players.begin();
for(; Iter != players.end(); Iter++)
Iter->clear();
totalgo = 0;
}
void deal() {
//发牌,由于reshuffle()中的牌实际上是按顺序排列的,这里就是从vector中随机抽出一张牌来,然后在vector中将其删除。
for(int i = 0; i < players.size(); i++) {
int todeal = ( (double)rand() / (double)RAND_MAX * poker.size() );
players[i].get(poker[todeal]);
poker.erase(poker.begin()+todeal);
}
}
void go() {
//简化了一下,玩家永远坐庄,所有人一定会跟同样的筹码(我懒得想了)
int igo;
gotoxy(1, 23); cout << "How many do you want to go? ";
gotoxy(28, 23); cin >> igo;
totalgo += players[0].go(igo);
vector<Player>::iterator Iter = players.begin();
for(Iter++; Iter != players.end(); Iter++)
totalgo += Iter->go(igo);
int max = 0;
for(int i = 1; i < players.size(); i++)
if(players[i].score() > players[max].score())
max = i;
players[max].win(totalgo);
gotoxy(40, 10); cout << players[max].getName() << " win! ";
}
bool finish() {
//判断是不是继续玩下去,就得有人要输衣服了...
bool flag = false;
vector<Player>::iterator Iter = players.begin();
for(; Iter != players.end(); Iter++)
if(Iter->getChp() <= 0)
flag = true;
return flag;
}
void show() {
//显示自己的牌,对手的显示牌背。
vector<Player>::iterator Iter = players.begin();
Iter->status();
for(Iter++; Iter != players.end(); Iter++)
Iter->hide();
}
void reveal() {
//显示所有人的牌。
vector<Player>::iterator Iter = players.begin();
for(; Iter != players.end(); Iter++)
Iter->status();
}
};
这样的设计虽然“面向对象了”,可我总觉得在哪儿有什么别扭的??不怕你笑话,我以前没学过C++,刚刚接触一个多月。一挠头全是头皮削...
下载(BCC5.5编译)>>>
- 扎金花
- 扎金花
- javase扎金花程序
- 扎金花概率详解
- 搜狐 扎金花
- JAVA学习--扎金花
- 扎金花扑克牌逻辑判定
- 搜狐笔试题:扎金花
- 简易扎金花java程序
- 牛客网---2016---搜狐扎金花
- 扎金花赌博小程序JAVA源码
- 写一个《扎金花》程序自己玩。
- 扎金花,单人,局域网均可 Delphi7
- “扎金花FANS”进行了改进
- 每人都有两大炸弹的扎金花2012
- 扎金花大小比较算法(Java版)
- 搜狐2016笔试1 扎金花
- 扎金花 游戏开发细节与部分代码
- 忙...
- ASP.NET 2.0 本地化功能:本地化 Web 应用程序的新方法
- 第五章笔记——《TC++PL》
- 遭遇Viking/威金新变种、Trojan-PSW.Win32.WOW.do等(三)
- 刚刚看了遍HTML语言的教程
- 扎金花
- 网页类型Mime Types
- 那时候我们除了会写软件 什么也不会做(丁磊2006于母校演讲)
- 一个老程序员的心里话说到人的心坎
- 你的公司叫什么?著名IT公司名字的来历
- 用 QT Designer 來快速學習 QT
- 事务日志处理
- 图象处理
- 管理与技术的距离