Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

AI finally introduced

  • Loading branch information...
commit 4c781d3681dedb50b6acb0dd1623bedf39f90247 1 parent 59b43e7
@NikolaYolov authored
View
37 inc/cmp_plr.h
@@ -1,20 +1,53 @@
#if !defined(_COMPUTER_PLAYER_H__)
#define _COMPUTER_PLAYER_H__
+#include <QThread>
#include "player.h"
+#include "gm_brd.h"
+
+class wrk_thrd
+ : public QThread
+{
+public:
+ turn des_;
+ wrk_thrd(QObject *, plr_clr );
+ void set_brd(const gm_brd &);
+ virtual ~wrk_thrd();
+
+protected:
+ void run();
+
+private:
+ int a_b(int a, int b, plr_clr c, int lvl, bool skp);
+
+private:
+ std::vector<gm_brd> brd_stck_;
+ plr_clr clr_;
+};
/**
* This class in the interface for the algorithms.
*/
class cmp_plr
- : public player
+ : public QObject
+ , public player
{
+ Q_OBJECT
public:
cmp_plr(gm_mst &, plr_clr );
/**
* This method makes one move using mix-max algorithm.
*/
- virtual void mk_mv(/*in*/ gm_brd &, /*in*/ time_t );
+ virtual void mk_mv(const /*in*/ gm_brd &, /*in*/ time_t );
+
+private slots:
+/**
+ * This informs the game master that the human has make their move.
+ */
+ void do_mv();
+
+protected:
+ wrk_thrd worker_;
};
#endif //_COMPUTER_PLAYER_H__
View
4 inc/gm_brd.h
@@ -37,8 +37,8 @@ class gm_brd
*/
void gen_all_mvs(/*in*/ plr_clr , /*out*/ std::vector<move>& ) const;
- plr_clr get_cell(move );
- plr_clr get_cell(int );
+ plr_clr get_cell(move ) const;
+ plr_clr get_cell(int ) const;
void set_cell(move , plr_clr );
void set_cell(int , plr_clr );
View
2  inc/hmn_plr.h
@@ -15,7 +15,7 @@ class hmn_plr
/**
* This method makes one move using the graphical interface.
*/
- virtual void mk_mv(/*in*/ gm_brd &, /*in*/ time_t );
+ virtual void mk_mv(const /*in*/ gm_brd &, /*in*/ time_t );
/**
* This informs the game master that the human has make their move.
View
6 inc/player.h
@@ -13,9 +13,10 @@ class gm_mst;
*/
enum plr_clr : char
{
- pc_free,
+ pc_free = 0,
pc_wht,
pc_blc,
+ pc_cnt, // count
};
/**
@@ -30,8 +31,9 @@ class player
* This virtual method represents the main interface for the human and cumputer players.
* It is called when the caller asks the player to move and the player starts 'thinking'.
*/
- virtual void mk_mv(/*in*/ gm_brd &, /*in*/ time_t ) = 0;
+ virtual void mk_mv(const /*in*/ gm_brd &, /*in*/ time_t ) = 0;
plr_clr get_clr();
+ virtual ~player(){};
protected:
gm_mst &ownr_;
View
1  inc/vis_brd.h
@@ -19,6 +19,7 @@ class vis_brd
int get_hz_sz() const;
int get_vt_sz() const;
void set_plr_brd(hmn_plr &, const gm_brd &);
+ void set_cmp_brd(const gm_brd &b);
void dctv();
protected:
View
173 src/cmp_plr.cpp
@@ -1,18 +1,179 @@
-#include "cassert"
+#include <cassert>
+#include <vector>
+#include <QDebug>
+#include "gm_mst.h"
#include "cmp_plr.h"
+#include "vis_brd.h"
+
+const int max_lvl = 8;
cmp_plr::cmp_plr(gm_mst &o, plr_clr c)
: player(o, c)
+ , worker_(0, c)
{
+ connect(&worker_, SIGNAL(finished()), this, SLOT(do_mv()));
}
//virtual
-void cmp_plr::mk_mv(gm_brd &brd, time_t tm_lft)
+void cmp_plr::mk_mv(const gm_brd &brd, time_t )
+{
+ vis_brd* vb = ownr_.get_vbrd();
+ assert(vb);
+ vb->set_cmp_brd(brd);
+ worker_.set_brd(brd);
+ worker_.start(QThread::LowestPriority);
+}
+
+void cmp_plr::do_mv()
+{
+ assert(worker_.isFinished());
+ ownr_.acpt_trn(worker_.des_);
+}
+
+wrk_thrd::wrk_thrd(QObject *o, plr_clr c)
+ : QThread(o)
+ , clr_(c)
+ , brd_stck_(max_lvl + 1)
+{
+ ;
+}
+
+int on_hrst(plr_clr c, const gm_brd &b)
+{
+ int scr_tbl[pc_cnt];
+ scr_tbl[pc_free] = 0;
+ scr_tbl[c] = 1;
+ scr_tbl[(c == pc_wht)? pc_blc : pc_wht] = -1;
+
+ int d = 0;
+ const int c00 = 0;
+ const int c0x = b.get_wdth() - 1;
+ const int cy0 = b.get_size() - b.get_wdth();
+ const int cyx = b.get_size() - 1;
+
+ for (index_t i = c00; i <= c0x; ++i)
+ d += 10 * scr_tbl[b.get_cell(i)];
+
+ for (index_t i = c0x; i <= cyx; i += b.get_wdth())
+ d += 10 * scr_tbl[b.get_cell(i)];
+
+ for (index_t i = c00; i <= cy0; i += b.get_wdth())
+ d += 10 * scr_tbl[b.get_cell(i)];
+
+ for (index_t i = cy0; i <= cyx; ++i)
+ d += 10 * scr_tbl[b.get_cell(i)];
+
+ for (index_t i = c00; i <= cyx; ++i)
+ d += scr_tbl[b.get_cell(i)];
+
+ return d;
+}
+
+int off_hrst(plr_clr c, const gm_brd &b)
+{
+ int scr_tbl[pc_cnt];
+ scr_tbl[pc_free] = 0;
+ scr_tbl[c] = 100;
+ scr_tbl[(c == pc_wht)? pc_blc : pc_wht] = -100;
+
+ int d = 0;
+ const int c00 = 0;
+ const int c0x = b.get_wdth() - 1;
+ const int cy0 = b.get_size() - b.get_wdth();
+ const int cyx = b.get_size() - 1;
+
+ for (index_t i = c00; i <= cyx; ++i)
+ d += scr_tbl[b.get_cell(i)];
+
+ return d;
+}
+
+void wrk_thrd::set_brd(const gm_brd &b)
+{
+ brd_stck_[0] = b;
+}
+
+char *t1 = "\t";
+char *t2 = "\t\t";
+char *t3 = "\t\t\t";
+char *t4 = "\t\t\t\t";
+char *t5 = "\t\t\t\t\t";
+char *t6 = "\t\t\t\t\t\t";
+char *t7 = "\t\t\t\t\t\t\t";
+char *t8 = "\t\t\t\t\t\t\t\t";
+char *ts[8] = { t1, t2, t3, t4, t5, t6, t7, t8 };
+
+int wrk_thrd::a_b(int a, int b, plr_clr c, int lvl, bool skp)
+{
+ if (lvl == max_lvl)
+ {
+ int res = on_hrst(c, brd_stck_[lvl]);
+ return (clr_ == c)? res : - res;
+ }
+
+ std::vector<move> mvs;
+ brd_stck_[lvl].gen_all_mvs(c, mvs);
+ plr_clr opp_c = (c == pc_wht)? pc_blc : pc_wht;
+
+ if (mvs.empty())
+ {
+ if (skp)
+ {
+ int res = off_hrst(c, brd_stck_[lvl]);
+ return (clr_ == c)? res : - res;
+ }
+ else
+ {
+ brd_stck_[lvl + 1] = brd_stck_[lvl];
+ return -a_b(-b, -a, opp_c, lvl + 1, true);
+ }
+ }
+
+ for (int i = 0; i < static_cast<int>(mvs.size()); ++i)
+ {
+ brd_stck_[lvl + 1] = brd_stck_[lvl];
+ brd_stck_[lvl + 1].do_mv(mvs[i], c);
+ a = std::max(a, -a_b(-b, -a, opp_c, lvl + 1, false));
+// qDebug() << ts[lvl] << a;
+ if (b <= a)
+ break;
+ }
+ return a;
+}
+
+void wrk_thrd::run()
+{
+ std::vector<move> mvs;
+ brd_stck_[0].gen_all_mvs(clr_, mvs);
+
+ if (!mvs.empty())
+ {
+ plr_clr opp_c = (clr_ == pc_wht)? pc_blc : pc_wht;
+ int besti = -1;
+ int bestsc = -0x7fffffff;
+
+ for (int i = 0; i < static_cast<int>(mvs.size()); ++i)
+ {
+ brd_stck_[1] = brd_stck_[0];
+ brd_stck_[1].do_mv(mvs[i], clr_);
+ int a = -a_b(-0x7fffffff, -bestsc, opp_c, 1, false);
+ if (a > bestsc)
+ {
+ bestsc = a;
+ besti = i;
+ }
+// qDebug() << bestsc;
+ }
+ des_ = { mvs[besti], mesg() };
+ }
+ else
+ des_.mesg_.msg_ = mesg::m_skip;
+// qDebug() << "-----------------------------------------------------------------";
+}
+
+wrk_thrd::~wrk_thrd()
{
- /**
- * Unimplemented!
- */
- assert(false);
+ assert(isFinished());
}
View
4 src/gm_brd.cpp
@@ -144,12 +144,12 @@ void gm_brd::gen_all_mvs(plr_clr plr, std::vector<move>& res) const
}
-plr_clr gm_brd::get_cell(move m)
+plr_clr gm_brd::get_cell(move m) const
{
return brd_[m.xy_];
}
-plr_clr gm_brd::get_cell(int m)
+plr_clr gm_brd::get_cell(int m) const
{
return brd_[m];
}
View
2  src/gm_mgr.cpp
@@ -32,6 +32,8 @@ gm_mgr::gm_mgr(QApplication *app)
opt_->wdth_ = 8;
opt_->hght_ = 8;
+ opt_->pl1_ = opts::pt_hmn;
+ opt_->pl2_ = opts::pt_cmp;
vb_ = new vis_brd(m_wnd_, 45, 45, gm_brd(opt_->wdth_, opt_->hght_));
View
4 src/gm_mst.cpp
@@ -153,8 +153,8 @@ void gm_mst::_init()
assert(opts_.hght_ > 1 && opts_.wdth_ > 1);
c_brd_.rst();
- plrs_[0] = (opts_.pl1_ == opts::pt_hmn) ? static_cast<player*>(new hmn_plr(*this, pc_wht)) : static_cast<player*>(new cmp_plr(*this, pc_wht));
- plrs_[1] = (opts_.pl2_ == opts::pt_hmn) ? static_cast<player*>(new hmn_plr(*this, pc_blc)) : static_cast<player*>(new cmp_plr(*this, pc_blc));
+ plrs_[0] = (opts_.pl1_ == opts::pt_hmn) ? dynamic_cast<player*>(new hmn_plr(*this, pc_wht)) : dynamic_cast<player*>(new cmp_plr(*this, pc_wht));
+ plrs_[1] = (opts_.pl2_ == opts::pt_hmn) ? dynamic_cast<player*>(new hmn_plr(*this, pc_blc)) : dynamic_cast<player*>(new cmp_plr(*this, pc_blc));
trn_n_ = 0;
c_plr_ = pc_wht;
View
2  src/hmn_plr.cpp
@@ -11,7 +11,7 @@ hmn_plr::hmn_plr(gm_mst& o, plr_clr c)
}
//virtual
-void hmn_plr::mk_mv(gm_brd &brd, time_t tm_lft)
+void hmn_plr::mk_mv(const gm_brd &brd, time_t tm_lft)
{
vis_brd* vb = ownr_.get_vbrd();
assert(vb);
View
19 src/vis_brd.cpp
@@ -29,13 +29,16 @@ static bool mvs_cmp(const move &m1, const move &m2)
return m1.xy_ < m2.xy_;
}
+static bool mvs_n_cmp(const move &m1, const move &m2)
+{
+ return m1.xy_ > m2.xy_;
+}
+
void vis_brd::sort_mvs()
{
- assert(!pos_mvs_.empty());
std::sort(pos_mvs_.begin(), pos_mvs_.end(), mvs_cmp);
}
-
void vis_brd::set_plr_brd(hmn_plr &p, const gm_brd &b)
{
assert((snpsht_.get_wdth() == b.get_wdth()) && snpsht_.get_hght() == b.get_hght());
@@ -43,6 +46,7 @@ void vis_brd::set_plr_brd(hmn_plr &p, const gm_brd &b)
plr_ = &p;
snpsht_ = b;
snpsht_.gen_all_mvs(plr_->get_clr(), pos_mvs_);
+ sort_mvs();
repaint();
if (pos_mvs_.empty())
@@ -53,6 +57,15 @@ void vis_brd::set_plr_brd(hmn_plr &p, const gm_brd &b)
}
}
+void vis_brd::set_cmp_brd(const gm_brd &b)
+{
+ setMouseTracking(false);
+ plr_ = 0;
+ snpsht_ = b;
+ assert(hlght_x_ == hlght_y_ && hlght_y_ == -1);
+ repaint();
+}
+
int vis_brd::get_hz_sz() const
{
return fld_sz * snpsht_.get_wdth() + wdt;
@@ -163,6 +176,7 @@ void vis_brd::mousePressEvent(QMouseEvent *ev)
const QPoint& pnt = ev->pos();
turn t;
t.move_.xy_ = _clc_idx_x(pnt.x()) + _clc_idx_y(pnt.y()) * snpsht_.get_wdth();
+ assert(std::adjacent_find(pos_mvs_.begin(), pos_mvs_.end(), mvs_n_cmp) == pos_mvs_.end());
if (std::binary_search(pos_mvs_.begin(), pos_mvs_.end(), t.move_, mvs_cmp))
{
hlght_x_ = hlght_y_ = -1;
@@ -182,6 +196,7 @@ void vis_brd::mouseMoveEvent(QMouseEvent *ev)
hlght_y_ = _clc_idx_y(pnt.y());
struct move mv(hlght_x_ + hlght_y_ * snpsht_.get_wdth());
+ assert(std::adjacent_find(pos_mvs_.begin(), pos_mvs_.end(), mvs_n_cmp) == pos_mvs_.end());
if (std::binary_search(pos_mvs_.begin(), pos_mvs_.end(), mv, mvs_cmp) == false)
hlght_x_ = hlght_y_ = -1;
repaint();
Please sign in to comment.
Something went wrong with that request. Please try again.