界面采用Qt實現,非常簡單而丑的界面。。。
功能全了,主要有:
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();
}