界面采用Qt实现,非常简单而丑的界面。。。

cvp

pvc

功能全了,主要有:

1.CVP你想个数字,电脑来猜,每猜一次你需要告诉电脑?A?B

2.PVC电脑随机生成数字,你来猜。

输入框内你可以修改备选的数字。

注意让电脑猜的话,数字多了会非常慢。我的算法问题。。。。

健壮性没有考虑,所以,尽量正常玩吧^_^

PVC就不用说了,随机选数字然后提示给用户几A几B就行。

CVP主要是开始时生成一个可选集合(所有可能的数字),再根据用户输入一次次的缩小可选集。

接下来从可选集给出数字,给出的策略可以自己制定,我写了很简单的一种可能。

代码里都分开了,如果有人有兴趣看的话应该不会难看懂~看不懂或者哪里需要改进的请给我留言O(∩_∩)O探讨。

PVC的数据类

#ifndef ABComputerGuess_H
#define ABComputerGuess_H
#include <string>
#include <vector>
class ABComputerGuess {

public:
ABComputerGuess();
void init();
std::string getGuessAnswer();
void setAnswerABs(int ACounter, int BCounter);
void setBaseDigit(std::string base);
std::string getBaseDigit() { return baseDigits; }

private:
bool compareTwoStrings(const std::string &str1, const std::string &str2, int ACounter, int BCounter);
int compareTwoStrings(const std::string &str1, const std::string &str2);
std::string chooseAnswer();
private:
std::string baseDigits;
std::vector<std::string> maybeSource;
std::string mAnswer;
};
#endif//ABComputerGuess_H

PVC的视图类

#ifndef ABCOMPUTERGUESSWIDGET_H
#define ABComputerGuessWidget_H
#include <QWidget>

class QLabel;
class QLineEdit;
class QPushButton;
class ABComputerGuess;

class ABComputerGuessWidget : public QWidget {

Q_OBJECT

public:
ABComputerGuessWidget(QWidget *parent = 0);

private slots:
void getABNumber();
void resetGame();

private:
void setGuessResult();

private:
ABComputerGuess *mABGuess;
QLineEdit *mACounterEdit;
QLineEdit *mBCounterEdit;
QLabel *mALabel;
QLabel *mBLabel;
QPushButton *mGuessButton;
QPushButton *mAgainButton;
QLabel *mResultShowingLabel;
QLineEdit *mBaseDigitEdit;
QString mAllResult;
};
#endif//ABComputerGuessWidget_H

CVP的数据类:

#ifndef ABPLAYERGUESS_H
#define ABPLAYERGUESS_H

#include <string>

class ABPlayerGuess {

public:
ABPlayerGuess();
void init();
std::string getBaseDigit() { return mBaseDigits; }
void setBaseDigit(std::string baseDigit) { mBaseDigits = baseDigit; }
std::string getRightAnswer() { return mRightNumber; }
void playerGuess(const std::string& str, int &ACounter, int &BCounter);

private:
int compareTwoStrings(const std::string &str1, const std::string &str2);

private:
std::string mRightNumber;
std::string mBaseDigits;
};
#endif//ABPLAYERGUESS_H

CVP的视图类:

#ifndef    ABPLAYERGUESSWIDGET_H
#define ABPLAYERGUESSWIDGET_H

#include <QWidget>

class QLineEdit;
class QLabel;
class QPushButton;
class ABPlayerGuess;
class QRegExpValidator;

class ABPlayerGuessWidget : public QWidget {

Q_OBJECT

public:
ABPlayerGuessWidget(QWidget *parent = 0);

private slots:
void onGuessed();
void resetGame();
void showRightAnswer();

private:
ABPlayerGuess *mGuessChecker;
QLineEdit *mGuessEdit;
QLabel *mResultShowingLabel;
QPushButton *mGuessButton;
QPushButton *mAgainButton;
QPushButton *mCheckButton;
QLineEdit *mBaseDigit;
QRegExpValidator *mGuessRuler;
QString mAllResult;
};
#endif//ABPLAYERGUESSWIDGET_H

整体视图类:

#ifndef ABGAMEWIDGET_H
#define ABGAMEWIDGET_H

#include <QTabWidget>
class ABComputerGuessWidget;
class ABPlayerGuessWidget;

class ABGameWidget : public QTabWidget {
Q_OBJECT

public:
ABGameWidget(QWidget *parent = 0);

private:
ABComputerGuessWidget *mComputerGuessWidget;
ABPlayerGuessWidget *mPlayerGuessWidget;
};
#endif//ABGAMEWIDGET_H

各个类的实现:

#include <set>
#include "ABComputerGuess.h"
ABComputerGuess::ABComputerGuess() :
baseDigits("0123456789")
{
init();
}

void ABComputerGuess::init()
{
int len = baseDigits.size();
maybeSource.clear();
for ( int i=0; i<len; ++i)
for ( int j=0; j<len; ++j)
for ( int p=0; p<len; ++p)
for ( int q=0; q<len; ++q)
if (i!=j && i!=p && i!=q && j!=p && j!=q && p!=q) {
std::string temp;
temp.push_back(baseDigits[i]);
temp.push_back(baseDigits[j]);
temp.push_back(baseDigits[p]);
temp.push_back(baseDigits[q]);
maybeSource.push_back(temp);
}
}

std::string ABComputerGuess::getGuessAnswer()
{
if (maybeSource.size()==0)
return std::string("error!");
//mAnswer = maybeSource[0];
mAnswer = chooseAnswer();
return mAnswer;
}

void ABComputerGuess::setAnswerABs(int ACounter, int BCounter)
{
if (ACounter>=0&&ACounter<=4&&BCounter>=0&&BCounter<=4) {
std::vector<std::string>::iterator iter=maybeSource.begin();
while (iter!=maybeSource.end()) {
if (!compareTwoStrings(mAnswer, *iter, ACounter, BCounter))
iter = maybeSource.erase(iter);
else
++iter;
}
}
}

int ABComputerGuess::compareTwoStrings(const std::string &str1, const std::string &str2)
{
int acounter = 0;
int bcounter = 0;
for ( size_t i=0; i<str1.size(); ++i)
for ( size_t j=0; j<str2.size(); ++j) {
if (str1[i]==str2[j]) {
if (i==j) {
++acounter;
} else {
++bcounter;
}
}
}
return acounter*10+bcounter;

}
bool ABComputerGuess::compareTwoStrings(const std::string &str1, const std::string &str2, int ACounter, int BCounter)
{
int counter = compareTwoStrings(str1,str2);
int bcounter = counter%10;
int acounter = counter/10%10;

return ((ACounter==acounter) && (BCounter==bcounter));
}

void ABComputerGuess::setBaseDigit(std::string base)
{
baseDigits = base;
init();
}

std::string ABComputerGuess::chooseAnswer()
{
int len = baseDigits.size();
size_t maxResultKinds = 0;
bool isLastinmaybeSource = false;
std::string guessAnswer;
for ( int i=0; i<len; ++i)
for ( int j=0; j<len; ++j)
for ( int p=0; p<len; ++p)
for ( int q=0; q<len; ++q)
if (i!=j && i!=p && i!=q && j!=p && j!=q && p!=q) {
std::string temp;
temp.push_back(baseDigits[i]);
temp.push_back(baseDigits[j]);
temp.push_back(baseDigits[p]);
temp.push_back(baseDigits[q]);
std::set<int> resultSet;
size_t length = maybeSource.size();
for ( size_t i=0; i<length; ++i) {
resultSet.insert(compareTwoStrings(maybeSource[i],temp));
}
if (resultSet.size()>=maxResultKinds) {
bool isInMaybeSource = (resultSet.find(40)!=resultSet.end());
if (resultSet.size()==maxResultKinds) {
if (isInMaybeSource && !isLastinmaybeSource) {
isLastinmaybeSource = true;
guessAnswer = temp;
}
} else {
isLastinmaybeSource = isInMaybeSource;
guessAnswer = temp;
maxResultKinds = resultSet.size();
}
}
if (maxResultKinds==14 && isLastinmaybeSource) return guessAnswer;
}
return guessAnswer;
}

#include <string>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QIntValidator>
#include "ABComputerGuessWidget.h"
#include "ABComputerGuess.h"

ABComputerGuessWidget::ABComputerGuessWidget(QWidget *parent) :
QWidget(parent)
{
QHBoxLayout *leftTopLayout = new QHBoxLayout;
mACounterEdit = new QLineEdit(this);
mALabel = new QLabel("A", this);
mBCounterEdit = new QLineEdit(this);
mBLabel = new QLabel("B", this);
QIntValidator *validator = new QIntValidator(0,4,this);
mACounterEdit->setValidator(validator);
mBCounterEdit->setValidator(validator);
leftTopLayout->addWidget(mACounterEdit);
leftTopLayout->addWidget(mALabel);
leftTopLayout->addWidget(mBCounterEdit);
leftTopLayout->addWidget(mBLabel);

QVBoxLayout *leftLayout = new QVBoxLayout;
mResultShowingLabel = new QLabel(this);
leftLayout->addLayout(leftTopLayout);
leftLayout->addWidget(mResultShowingLabel);

mABGuess = new ABComputerGuess();

QVBoxLayout *rightLayout = new QVBoxLayout;
mGuessButton = new QPushButton("Guess",this);
mAgainButton = new QPushButton("Again",this);
mBaseDigitEdit = new QLineEdit(mABGuess->getBaseDigit().c_str(), this);
rightLayout->addWidget(mGuessButton);
rightLayout->addWidget(mAgainButton);
rightLayout->addWidget(mBaseDigitEdit);

QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);

setLayout(mainLayout);

setGuessResult();

connect(mACounterEdit, SIGNAL(returnPressed()), this, SLOT(getABNumber()));
connect(mBCounterEdit, SIGNAL(returnPressed()), this, SLOT(getABNumber()));
connect(mBaseDigitEdit, SIGNAL(returnPressed()), this, SLOT(resetGame()));
connect(mGuessButton, SIGNAL(clicked()), this, SLOT(getABNumber()));
connect(mAgainButton, SIGNAL(clicked()), this, SLOT(resetGame()));
}

void ABComputerGuessWidget::setGuessResult()
{
std::string guessNumber = mABGuess->getGuessAnswer();
mAllResult.append(guessNumber.c_str());
mResultShowingLabel->setText(mAllResult);
}

void ABComputerGuessWidget::getABNumber()
{
mABGuess->setAnswerABs(mACounterEdit->displayText().toInt(),
mBCounterEdit->displayText().toInt());
QString abNumberString = mACounterEdit->displayText() +
QString(1,'A') +
mBCounterEdit->displayText() +
QString(1,'B');
mAllResult.append(" | ").append(abNumberString).append("\n");
setGuessResult();
}

void ABComputerGuessWidget::resetGame()
{
mABGuess->setBaseDigit(mBaseDigitEdit->displayText().toUtf8().data());
mABGuess->init();
mAllResult.clear();
setGuessResult();
mACounterEdit->setText("");
mBCounterEdit->setText("");
}

#include <QLabel>
#include <QMessageBox>
#include "ABGameWidget.h"
#include "ABComputerGuessWidget.h"
#include "ABPlayerGuessWidget.h"
ABGameWidget::ABGameWidget(QWidget *parent) :
QTabWidget(parent)
{
mPlayerGuessWidget = new ABPlayerGuessWidget(this);
mComputerGuessWidget = new ABComputerGuessWidget(this);
addTab(mPlayerGuessWidget, tr("PVC"));
addTab(mComputerGuessWidget, tr("CVP"));
QLabel *infoLabel = new QLabel(tr("<b>AB Game:</b><br></br>\n\
1.PVC:computer will offer one number(secret at first).\n\
Guess the number by the xAxB responsed by computer.\n\
2.CVP:computer will guess the number you offered.\n\
And you should offer xAxB as the result,too.\n\
The base characters can be setted in the lineedit, input and pressed enter\n\
Contact me if you found some big error......email: izualzhy@163.com"
));
infoLabel->setTextFormat(Qt::PlainText);
addTab(infoLabel,tr("About"));
}


#include <stdlib.h>
#include <time.h>
#include "ABPlayerGuess.h"
ABPlayerGuess::ABPlayerGuess() :
mBaseDigits("0123456789")
{
//init();
}

void ABPlayerGuess::init()
{
int len = mBaseDigits.size();
mRightNumber.clear();
while (mRightNumber.size()!=4) {
char temp = mBaseDigits[rand()%len];
if (mRightNumber.find(temp)==std::string::npos)
mRightNumber.append(1,temp);
}
}

void ABPlayerGuess::playerGuess(const std::string &str, int &ACounter, int &BCounter)
{
int counter = compareTwoStrings(str, mRightNumber);
BCounter = counter%10;
ACounter = counter/10%10;
}

int ABPlayerGuess::compareTwoStrings(const std::string &str1, const std::string &str2)
{
int acounter = 0;
int bcounter = 0;
for ( size_t i=0; i<str1.size(); ++i)
for ( size_t j=0; j<str2.size(); ++j) {
if (str1[i]==str2[j]) {
if (i==j) {
++acounter;
} else {
++bcounter;
}
}
}
return acounter*10+bcounter;

}

#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QRegExpValidator>
#include "ABPlayerGuessWidget.h"
#include "ABPlayerGuess.h"
ABPlayerGuessWidget::ABPlayerGuessWidget(QWidget *parent) :
QWidget(parent)
{
mGuessChecker = new ABPlayerGuess;
QVBoxLayout *rightLayout = new QVBoxLayout;
mGuessEdit = new QLineEdit(this);
mGuessRuler = new QRegExpValidator(mGuessEdit);
mResultShowingLabel = new QLabel(this);
rightLayout->addWidget(mGuessEdit);
rightLayout->addWidget(mResultShowingLabel);

QVBoxLayout *leftLayout = new QVBoxLayout;
mGuessButton = new QPushButton("Guess",this);
mAgainButton = new QPushButton("Again",this);
mBaseDigit = new QLineEdit(mGuessChecker->getBaseDigit().c_str(),this);
mCheckButton = new QPushButton("Check",this);
leftLayout->addWidget(mGuessButton);
leftLayout->addWidget(mAgainButton);
leftLayout->addWidget(mBaseDigit);
leftLayout->addWidget(mCheckButton);

QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(rightLayout);
mainLayout->addLayout(leftLayout);
setLayout(mainLayout);
connect(mGuessEdit,SIGNAL(returnPressed()),this,SLOT(onGuessed()));
connect(mGuessButton,SIGNAL(clicked()),this,SLOT(onGuessed()));
connect(mAgainButton,SIGNAL(clicked()),this,SLOT(resetGame()));
connect(mCheckButton,SIGNAL(clicked()),this,SLOT(showRightAnswer()));
connect(mBaseDigit,SIGNAL(returnPressed()),this,SLOT(resetGame()));

resetGame();
}

void ABPlayerGuessWidget::onGuessed()
{
int a,b;
QString playerGuessString = mGuessEdit->displayText();
for ( int i=0; i<playerGuessString.size(); ++i)
for ( int j=0; j<playerGuessString.size(); ++j) {
if ((i!=j) && (playerGuessString[i]==playerGuessString[j]))
return;
}

mGuessChecker->playerGuess(playerGuessString.toUtf8().data(),a,b);
QString guessAnswer = QString::number(a) + QString(QChar('A'))
+ QString::number(b) + QString(QChar('B')) + QString(QChar('\n'));
mAllResult = playerGuessString.append(" | ").append(guessAnswer) + mAllResult;
mResultShowingLabel->setText(mAllResult);
mGuessEdit->setText("");
}

void ABPlayerGuessWidget::resetGame()
{
if (mBaseDigit->displayText().size()<4) {
mBaseDigit->setText("0123456789");
}
mGuessChecker->setBaseDigit(mBaseDigit->displayText().toUtf8().data());
mGuessChecker->init();
mGuessEdit->setText("");
mAllResult.clear();
mResultShowingLabel->setText(mAllResult);
QString rulerString = QString("[")+mBaseDigit->displayText()+QString("]{4}");
mGuessRuler->setRegExp(QRegExp(rulerString));
mGuessEdit->setValidator(mGuessRuler);
}

void ABPlayerGuessWidget::showRightAnswer()
{
QMessageBox::about(this,"Answer",mGuessChecker->getRightAnswer().c_str());
resetGame();
}