Commit 999fb7ea by Szeberényi Imre

v0

parent 8514b46c
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="amoba" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/amoba" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
<Add option="-DDMEMTRACE" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/amoba" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-pedantic" />
<Add option="-std=c++11" />
<Add option="-Wall" />
<Add option="-DMEMTRACE" />
</Compiler>
<Unit filename="disc.cpp" />
<Unit filename="disc.h" />
<Unit filename="main.cpp" />
<Unit filename="memtrace.cpp" />
<Unit filename="memtrace.h" />
<Unit filename="table.cpp" />
<Unit filename="table.h" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<diagram program="umlet" version="13.2">
<zoom_level>8</zoom_level>
<element>
<id>UMLClass</id>
<coordinates>
<x>168</x>
<y>88</y>
<w>336</w>
<h>232</h>
</coordinates>
<panel_attributes>Table
--
- t: vector&lt;Disc*&gt;
- MaxDir: int = 8
--
- validx(): bool
- validy(): bool
+ Table(nx: int, ny: int)
+ getNeighbors(x: int, y: int): neighbors_type
+ getNext(x: int, y: int, int dir): Disc*
+ probe(x: int, y: int): bool
+ newPosition(x: int, y: int): Position
+ setDisc(d: Dsic*): void
+ list(): void
</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>UMLClass</id>
<coordinates>
<x>576</x>
<y>88</y>
<w>248</w>
<h>176</h>
</coordinates>
<panel_attributes>Position
--
- x: int
- y: int
- tp: Table*
--
+ Position(x: int, y: int t: Table*)
+ getNeighbors(): neighbors_type;
+ getNext(int dir): Disc*
+ getx(): int
+ gety(): int
</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>504</x>
<y>80</y>
<w>88</w>
<h>40</h>
</coordinates>
<panel_attributes>lt=-(+)
</panel_attributes>
<additional_attributes>90.0;30.0;10.0;30.0</additional_attributes>
</element>
<element>
<id>UMLClass</id>
<coordinates>
<x>168</x>
<y>408</y>
<w>368</w>
<h>168</h>
</coordinates>
<panel_attributes>Disc
--
- pos: Position
# color: color_type;
--
- setColor(col: color_type): void
+ Disc(pos: Position, clo: color_type = white)
+ checkAll(): void
+ check(col: color_type, dir: int, max: int = 4): bool
+ getColor(): color_type
</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>344</x>
<y>312</y>
<w>24</w>
<h>112</h>
</coordinates>
<panel_attributes>lt=&lt;&lt;&lt;&lt;&lt;-</panel_attributes>
<additional_attributes>10.0;10.0;10.0;120.0</additional_attributes>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>488</x>
<y>256</y>
<w>136</w>
<h>168</h>
</coordinates>
<panel_attributes>lt=&lt;&lt;&lt;&lt;&lt;-</panel_attributes>
<additional_attributes>10.0;190.0;150.0;10.0</additional_attributes>
</element>
</diagram>
/**
* \file: disc.cpp
*
*/
#include "disc.h"
#include "memtrace.h"
/// Minden irányban ellenőrizzük, hogy kialakult-e a sor
/// @return true, ha kialakult a megfelelő hosszú sor
bool Disc::checkAll() {
Table::neighbors_type nb = pos.getNeighbors();
for(Table::neighbors_type::iterator it= nb.begin(); it != nb.end(); ++it) {
if ((it->second)->check(color, it->first)) {
setColor(red); /// kialakult, átváltjuk kezdő korongot is
return true;
}
}
return false;
}
/// Adott irányban ellenőrizzük, hogy kialakult-e a sor
/// @param col - szín
/// @param dir - irány (0..Table::MaxDir)
/// @param max - azonos korongok száma
/// @return true, ha kialakult a max hosszú sor
bool Disc::check(color_type col, int dir, int max) {
if (col == color) {
if (--max == 0) {
setColor(red); /// megvan a kellő hossz
return true;
} else {
Disc *dp = pos.getNext(dir);
if (dp && dp->check(col, dir, max)) {
setColor(red); /// siker, megy a rekurzió vissza
return true;
}
}
}
return false;
}
/*
* \file: Disc.h
*/
#ifndef DISC_H
#define DISC_H
#include "table.h"
class Disc {
Table::Position pos; ///< tábla pozíció tárolásához
color_type color; ///< korong színe
void setColor(color_type col) { color = col;}
public:
/// Ha új korongot teszünk le, akkor meg kell nézni hogy kialakult-e valahol a sor.
/// @param pos - pozíció
/// @param col - szín
Disc(Table::Position pos, color_type col = white) :pos(pos), color(col) { }
/// Az összes szomszéddal megnézi
bool checkAll();
/// Egy adott irányt ellenõriz
/// @param col - szín
/// @param dir - irány (0..Table::MaxDir)
/// @param max - azonos korongok száma
bool check(color_type col, int dir, int max = 4);
/// @return pozíció
Table::Position getPosition() const { return pos; }
/// @return szín
color_type getColor() const { return color; }
};
#endif // DISC_H
#ifndef GTEST_LITE_H
#define GTEST_LITE_H
/**
* \file gtest_lite.h
*
* Google gtest keretrendszerhez hasonló rendszer.
* Sz.I. 2015., 2016., 2017. (_Has_X)
*
* A tesztelés legalapvetőbb funkcióit támogató függvények és makrók.
* Nem szálbiztos megvalósítás.
* Szabadon felhasználható, bővíthető.
*
* Használati példa:
* Teszteljük az f(x)=2*x függvényt:
* int f(int x) { return 2*x; }
*
* int main() {
* TEST(TeszEsetNeve, TesztNeve)
* EXPECT_EQ(0, f(0));
* EXPECT_EQ(4, f(2)) << "A függvény hibás eredményt adott" << std::endl;
* ...
* END
* ...
*
* A működés részleteinek megértése szorgalmi feladat.
*/
#include <iostream>
#include <cassert>
#include <cmath>
#include <cstring>
#include <limits>
#include <string>
#include <fstream>
// Két makró az egyes tesztek elé és mögé:
// A két makró a kapcsos zárójelekkel egy új blokkot hoz létre, amiben
// a nevek lokálisak, így elkerülhető a névütközés.
/// Teszt kezdete. A makró paraméterezése hasonlít a gtest
/// paraméterezéséhez. Így az itt elkészített testek könnyen átemelhetők
/// a gtest keretrendszerbe.
/// @param C - teszteset neve (csak a gtest kompatibilitás miatt van külön neve az eseteknek)
/// @param N - teszt neve
#define TEST(C, N) { gtest_lite::test.begin(#C"."#N);
/// Teszteset vége.
#define END gtest_lite::test.end(); }
// Eredmények vizsgálatát segítő makrók.
// A paraméterek és a funkciók a gtest keretrendszerrel megegyeznek.
/// Sikeres teszt makrója
#define SUCCEED() gtest_lite::test.tstatus(true, __FILE__, __LINE__)
/// Sikertelen teszt makrója
#define FAIL() gtest_lite::test.tstatus(false, __FILE__, __LINE__)
/// Azonosságot elváró makró
#define EXPECT_EQ(expected, actual) EXPECTCMP((expected) == (actual), expected, actual)
/// Eltérést elváró makró
#define EXPECT_NE(expected, actual) EXPECTNE((expected) != (actual), expected, actual)
/// Igaz értéket elváró makró
#define EXPECT_TRUE(actual) EXPECTCMP(actual, "true", actual)
/// Hamis értéket elváró makró
#define EXPECT_FALSE(actual) EXPECTCMP(!(actual), "false", actual)
/// Valós számok azonosságát elváró makró
#define EXPECT_DOUBLE_EQ(expected, actual) EXPECTCMP(gtest_lite::almostEQ(expected, actual), expected, actual)
/// C stringek (const char *) azonosságát tesztelő makró
#define EXPECT_STR_EQ(expected, actual) ((actual != NULL) ? \
EXPECTCMP(strcmp(expected, actual) == 0, expected, actual) : \
EXPECT(false, "STR_EQ NULL pointert kapott!"))
/// C stringek (const char *) eltéréset tesztelő makró
#define EXPECT_STR_NE(expected, actual) ((actual != NULL) ? \
EXPECTNE(strcmp(expected, actual) != 0, expected, actual) : \
EXPECT(false, "STR_EQ NULL pointert kapott!"))
/// Kivételt várunk
#define EXPECT_THROW(statement, exception_type) try { gtest_lite::test.tmp = false; statement; } \
catch (exception_type) { gtest_lite::test.tmp = true; } \
catch (...) { } \
EXPECTTHROW(statement, "kivetelt dob.", "nem dobott '"#exception_type"' kivetelt.")
/// Kivételt várunk és továbbdobjuk -- ilyen nincs a gtest-ben
#define EXPECT_THROW_THROW(statement, exception_type) try { gtest_lite::test.tmp = false; statement; } \
catch (exception_type) { gtest_lite::test.tmp = true; throw; } \
EXPECTTHROW(statement, "kivetelt dob.", "nem dobott '"#exception_type"' kivetelt.")
/// Nem várunk kivételt
#define EXPECT_NO_THROW(statement) try { gtest_lite::test.tmp = true; statement; } \
catch (...) { gtest_lite::test.tmp = false; }\
EXPECTTHROW(statement, "nem dob kivetelt.", "kivetelt dobott.")
/// Segédmakró egy adattag, vagy tagfüggvény létezésének tesztelésére futási időben
/// Ötlet:
/// https://cpptalk.wordpress.com/2009/09/12/substitution-failure-is-not-an-error-2
#define CREATE_Has_(X) \
template<typename T> struct Has_##X { \
struct Fallback { int X; }; \
struct Derived : T, Fallback {}; \
template<typename C, C> struct ChT; \
template<typename D> static char (&f(ChT<int Fallback::*, &D::X>*))[1]; \
template<typename D> static char (&f(...))[2]; \
static bool const member = sizeof(f<Derived>(0)) == 2; \
};
/// Segédfüggvény egy publikus adattag, vagy tagfüggvény létezésének tesztelésére fordítási időben
void hasMember(...) {}
/// -----------------------------------
/// Belső megvalósításhoz tartozó makrók, és osztályok.
/// Nem célszerű közvetlenül használni, vagy módosítani
/// -----------------------------------
/// EXPECT: makró, hogy könnyen lecserélhető legyen
#define EXPECT(expr, msg) gtest_lite::test.expect(expr, __FILE__, __LINE__, #msg)
/// EXPECTEXP: általános kifejezés kiértékelése
#define EXPECTEXP(expr, exp, act) gtest_lite::test.expect(expr, __FILE__, __LINE__, #expr) \
<< "**A(z) '"#act << "'kifejezes\n** erteke: " << std::boolalpha << (act) \
<< "\n** elvart: " << (exp) << std::endl
/// EXPECTCMP: összehasonlítás
#define EXPECTCMP(expr, exp, act) gtest_lite::test.expect(expr, __FILE__, __LINE__, #act) \
<< "**A(z) '"#act << "'kifejezes\n** erteke: " << std::boolalpha << (act) \
<< "\n** elvart: " << (exp) << std::endl
/// EXPECTNE: összehasonlítás
#define EXPECTNE(expr, exp, act) gtest_lite::test.expect(expr, __FILE__, __LINE__, #act) \
<< "**A(z) '"#act << "'kifejezes\n** erteke: " << std::boolalpha << (act) \
<< "\n** elvart, hogy nem: " << (exp) << std::endl
/// EXPECTTHROW: kivételkezelés
#define EXPECTTHROW(statement, exp, act) gtest_lite::test.expect(gtest_lite::test.tmp, __FILE__, __LINE__, #statement) \
<< "**Az utasitas " << (act) \
<< "\n**Azt vartuk, hogy " << (exp) << std::endl
/// gtest_lite: a keretrendszer függvényinek és objektumainak névtere
namespace gtest_lite {
/// Tesztek állapotát tároló osztály.
/// Egyetlen egy statikus példány keletkezik, aminek a
/// destruktora a futás végén hívódik meg.
struct Test {
int sum; ///< tesztek számlálója
int failed; ///< hibás tesztek
bool status; ///< éppen futó teszt státusza
bool tmp; ///< temp a kivételkezeléshez;
std::string name; ///< éppen futó teszt neve
std::fstream null; ///< nyelő, ha nem kell kiírni semmit
Test() :sum(0), failed(0), status(false), null("/dev/null") {}
/// Teszt kezdete
void begin(const char *n) {
name = n; status = true;
#ifndef CPORTA
std::cerr << "\n---> " << name << std::endl;
#endif // CPORTA
++sum;
}
/// Teszt vége
void end() {
#ifdef CPORTA
if (!status)
#endif // CPORTA
std::cerr << (status ? " SIKERES" : "** HIBAS ****") << "\t" << name << " <---" << std::endl;
}
/// Eredményt adminisztráló tagfüggvény True a jó eset.
std::ostream& expect(bool st, const char *file, int line, const char *expr) {
if (!st) {
++failed;
status = false;
std::string str(file);
size_t i = str.rfind("\\");
if (i == std::string::npos) i = str.rfind("/");
if (i == std::string::npos) i = 0; else i++;
return std::cerr << "\n**** HIBA: " << &file[i] << "(" << line << "): " << expr << " ****" << std::endl;
}
return null;
}
/// Eredményt adminisztráló tagfüggvény True a jó eset, mindig ír
std::ostream& tstatus(bool st, const char *file, int line) {
if (!st) {
++failed;
status = false;
}
std::string str(file);
size_t i = str.rfind("\\");
if (i == std::string::npos) i = str.rfind("/");
if (i == std::string::npos) i = 0; else i++;
return std::cerr << (status ? "** SIKERES" : "** HIBAS") << " TESZT "<< &file[i] << "(" << line << ") **" << std::endl;
}
/// Destruktor
~Test() {
#ifdef CPORTA
if (failed)
#endif // CPORTA
std::cerr << "\n==== TESZT VEGE ==== HIBAS/OSSZES: " << failed << "/" << sum << std::endl;
}
};
/// Egytelen statikus példány
static Test test;
/// Segédfüggvény valós számok összehasonlításához
/// Nem bombabiztos, de nekünk most jó lesz
/// Elméleti hátér:
/// http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
inline bool almostEQ(double a, double b) {
// eps: ha a relatív, vagy abszolút hiba ettől kisebb, akkor elfogadjuk
double eps = 10 * std::numeric_limits<double>::epsilon(); // 10-szer a legkisebb érték
if (a == b) return true;
if (fabs(a - b) < eps)
return true;
double aa = fabs(a);
double ba = fabs(b);
if (aa < ba) {
aa = ba;
ba = fabs(a);
}
return (aa - ba) < aa * eps;
}
} // namespace gtest_lite
#endif // GTEST_LITE_H
/*
* \file: Amoba.cpp
* Nem áll le, ha betelik a tábla
*
*/
#include <iostream>
#include "table.h"
#include "disc.h"
#include "memtrace.h"
using std::cin;
using std::cout;
using std::endl;
int main() {
Table t;
int x, y;
t.setDisc(new Disc(t.newPosition(3,3), white));
t.list();
char c = 'X';
do {
cout << c << " lepese: ";
if (t.jatekVege() || !(cin >> x >> y))
break;
if (t.probe(x,y)) {
color_type col = c == 'O' ? white : black;
t.setDisc(new Disc(t.newPosition(x,y), color_type(col)));
t.list();
c = c == 'X' ? 'O' : 'X'; // másik játékos
} else {
cout << "oda nem lephet!";
}
cout << endl;
} while (true);
cout << "Vege" << endl;
return 0;
}
/*********************************
Memoriaszivargas-detektor
Keszitette: Peregi Tamas, BME IIT, 2011
petamas@iit.bme.hu
Kanari: Szeberenyi Imre, 2013.,
VS 2012: Szeberényi Imre, 2015.,
mem_dump: 2016.
inclue-ok: 2017., 2018. 2019.
*********************************/
#ifndef MEMTRACE_H
#define MEMTRACE_H
#if defined(MEMTRACE)
/*ha definiálva van, akkor a hibakat ebbe a fajlba írja, egyébkent stderr-re*/
/*#define MEMTRACE_ERRFILE MEMTRACE.ERR*/
/*ha definialva van, akkor futas kozben lancolt listat epit. Javasolt a hasznalata*/
#define MEMTRACE_TO_MEMORY
/*ha definialva van, akkor futas kozben fajlba irja a foglalasokat*/
/*ekkor nincs ellenorzes, csak naplozas*/
/*#define MEMTRACE_TO_FILE*/
/*ha definialva van, akkor a megallaskor automatikus riport keszul */
#define MEMTRACE_AUTO
/*ha definialva van, akkor malloc()/calloc()/realloc()/free() kovetve lesz*/
#define MEMTRACE_C
#ifdef MEMTRACE_C
/*ha definialva van, akkor free(NULL) nem okoz hibat*/
#define ALLOW_FREE_NULL
#endif
#ifdef __cplusplus
/*ha definialva van, akkor new/delete/new[]/delete[] kovetve lesz*/
#define MEMTRACE_CPP
#endif
#if defined(__cplusplus) && defined(MEMTRACE_TO_MEMORY)
/*ha definialva van, akkor atexit helyett objektumot hasznal*/
/*ajanlott bekapcsolni*/
#define USE_ATEXIT_OBJECT
#endif
/******************************************/
/* INNEN NE MODOSITSD */
/******************************************/
#ifdef NO_MEMTRACE_TO_FILE
#undef MEMTRACE_TO_FILE
#endif
#ifdef NO_MEMTRACE_TO_MEMORY
#undef MEMTRACE_TO_MEMORY
#endif
#ifndef MEMTRACE_AUTO
#undef USE_ATEXIT_OBJECT
#endif
#ifdef __cplusplus
#define START_NAMESPACE namespace memtrace {
#define END_NAMESPACE } /*namespace*/
#define TRACEC(func) memtrace::func
#include <new>
#else
#define START_NAMESPACE
#define END_NAMESPACE
#define TRACEC(func) func
#endif
// THROW deklaráció változatai
#if defined(_MSC_VER)
// VS rosszul kezeli az __cplusplus makrot
#if _MSC_VER < 1900
// * nem biztos, hogy jó így *
#define THROW_BADALLOC
#define THROW_NOTHING
#else
// C++11 vagy újabb
#define THROW_BADALLOC noexcept(false)
#define THROW_NOTHING noexcept
#endif
#else
#if __cplusplus < 201103L
// C++2003 vagy régebbi
#define THROW_BADALLOC throw (std::bad_alloc)
#define THROW_NOTHING throw ()
#else
// C++11 vagy újabb
#define THROW_BADALLOC noexcept(false)
#define THROW_NOTHING noexcept
#endif
#endif
START_NAMESPACE
int allocated_blocks();
END_NAMESPACE
#if defined(MEMTRACE_TO_MEMORY)
START_NAMESPACE
int mem_check(void);
END_NAMESPACE
#endif
#if defined(MEMTRACE_TO_MEMORY) && defined(USE_ATEXIT_OBJECT)
#include <cstdio>
START_NAMESPACE
class atexit_class {
private:
static int counter;
static int err;
public:
atexit_class() {
#if defined(CPORTA) && !defined(CPORTA_NOSETBUF)
if (counter == 0) {
setbuf(stdout, 0);
setbuf(stderr, 0);
}
#endif
counter++;
}
int check() {
if(--counter == 0)
err = mem_check();
return err;
}
~atexit_class() {
check();
}
};
static atexit_class atexit_obj;
END_NAMESPACE
#endif/*MEMTRACE_TO_MEMORY && USE_ATEXIT_OBJECT*/
/*Innentol csak a "normal" include eseten kell, kulonben osszezavarja a mukodest*/
#ifndef FROM_MEMTRACE_CPP
#include <stdlib.h>
#ifdef __cplusplus
#include <iostream>
/* ide gyűjtjük a nemtrace-vel összeakadó headereket, hogy előbb legyenek */
#include <fstream> // VS 2013 headerjében van deleted definició
#include <sstream>
#include <vector>
#include <list>
#include <map>
#include <algorithm>
#include <functional>
#endif
#ifdef MEMTRACE_CPP
namespace std {
typedef void (*new_handler)();
}
#endif
#ifdef MEMTRACE_C
START_NAMESPACE
#undef malloc
#define malloc(size) TRACEC(traced_malloc)(size,#size,__LINE__,__FILE__)
void * traced_malloc(size_t size, const char *size_txt, int line, const char * file);
#undef calloc
#define calloc(count,size) TRACEC(traced_calloc)(count, size, #count","#size,__LINE__,__FILE__)
void * traced_calloc(size_t count, size_t size, const char *size_txt, int line, const char * file);
#undef free
#define free(p) TRACEC(traced_free)(p, #p,__LINE__,__FILE__)
void traced_free(void * p, const char *size_txt, int line, const char * file);
#undef realloc
#define realloc(old,size) TRACEC(traced_realloc)(old,size,#size,__LINE__,__FILE__)
void * traced_realloc(void * old, size_t size, const char *size_txt, int line, const char * file);
void mem_dump(void const *mem, size_t size, FILE* fp);
END_NAMESPACE
#endif/*MEMTRACE_C*/
#ifdef MEMTRACE_CPP
START_NAMESPACE
#undef set_new_handler
#define set_new_handler(f) TRACEC(_set_new_handler)(f)
void _set_new_handler(std::new_handler h);
void set_delete_call(int line, const char * file);
END_NAMESPACE
void * operator new(size_t size, int line, const char * file) THROW_BADALLOC;
void * operator new[](size_t size, int line, const char * file) THROW_BADALLOC;
void * operator new(size_t size) THROW_BADALLOC;
void * operator new[](size_t size) THROW_BADALLOC;
void operator delete(void * p) THROW_NOTHING;
void operator delete[](void * p) THROW_NOTHING;
/* Visual C++ 2012 miatt kell, mert háklis, hogy nincs megfelelő delete, bár senki sem használja */
void operator delete(void *p, int, const char *) THROW_NOTHING;
void operator delete[](void *p, int, const char *) THROW_NOTHING;
#define new new(__LINE__, __FILE__)
#define delete memtrace::set_delete_call(__LINE__, __FILE__),delete
#ifdef CPORTA
#define system(...) // system(__VA_ARGS__)
#endif
#endif /*MEMTRACE_CPP*/
#endif /*FROM_MEMTRACE_CPP*/
#endif /*MEMCHECK*/
#endif /*MEMTRACE_H*/
/*
* \file: table.cpp
*/
#include "table.h"
#include "disc.h"
#include "memtrace.h"
Table::Table(int nx, int ny) :vege(false), t(nx, std::vector<Disc*>(ny)) {
int k = 0;
/// Kitöltjük az irányok tábláját
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i != 0 || j != 0) {
dirs[k].dx = i;
dirs[k].dy = j;
k++;
}
}
}
}
Table::~Table() {
for (size_t i = 0; i < t.size(); i++)
for (size_t j = 0; j < t[0].size(); j++)
delete t[i][j];
}
/// Adott irányban levő szomszéd lekérdezése
/// @param x - X pozíció
/// @param y - Y pozíció
/// @param dir - irány [0..MaxDir]
/// @return szomszéd pointere, vagy null
Disc* Table::getNext(int x, int y, int dir) const {
int nx = x + dirs[dir].dx;
int ny = y + dirs[dir].dy;
if (validx(nx) && validy(ny))
return t[nx][ny];
else
return NULL;
}
/// Szomszédok lekérdezése.
/// @param x - X pozíció
/// @param y - Y pozíció
/// @return szomszédok map-je (irány, Disc*)
Table::neighbors_type Table::getNeighbors(int x, int y) {
neighbors_type nb;
for (int i = 0; i < MaxDir; i++) {
int nx = x + dirs[i].dx;
int ny = y + dirs[i].dy;
if (validx(nx) && validy(ny) && t[nx][ny] != NULL)
nb[i] = t[nx][ny];
}
return nb;
}
/// Adott hely tesztelése
/// @param x - X pozíció
/// @param y - Y pozíció
/// @return true, ha szabad a hely
bool Table::probe(int x, int y) {
if (validx(x) && validy(y) && t[x][y] == NULL)
return true;
return false;
}
/// Korong felrakása a táblára
/// @param d - korong pointere
void Table::setDisc(Disc* d) {
Position pos = d->getPosition();
t[pos.getx()][pos.gety()] = d;
// Megkérjük, hogy ellenőrizze, hogy van-e már elegendő korong
vege = d->checkAll();
}
/// Tabla kirajzolása
void Table::list() const {
std::cout << ' ';
for (size_t j = 0; j < t[0].size(); j++)
std::cout << "|" << j;
std::cout << "|\n";
for (size_t i = 0; i < t.size(); i++) {
std::cout << i;
for (size_t j = 0; j < t[0].size(); j++) {
Disc* dp = t[i][j];
if (dp == NULL)
std::cout << "|.";
else if (dp->getColor() == color_type(0))
std::cout << "|O";
else if (dp->getColor() == color_type(1))
std::cout << "|X";
else
std::cout << "|*";
}
std::cout << "|\n";
}
}
/*
* \file: Table.h
*/
#ifndef TABLE_H
#define TABLE_H
#include <iostream>
#include <vector>
#include <map>
enum color_type { white, black, red };
class Disc;
class Table {
bool vege;
std::vector<std::vector<Disc*> > t; ///< itt tároljuk a korongokat
static const int MaxDir = 8; ///< ennyi irányunk van
struct dir_type { int dx, dy; } dirs[MaxDir]; ///< irányokat tároló tömb
/// adott X pozíció érvényes?
/// @param x - X pozíció
/// @return true, ha érvényes
bool validx(size_t x) const { return x < t.size(); }
/// adott Y pozíció érvényes?
/// @param y - Y pozíció
/// @return true, ha érvényes
bool validy(size_t y) const { return y < t[0].size(); }
public:
class Position; ///< belső osztály a pozíció tárolására, absztrakció szintjén hasonlít az iterátorra
typedef std::map<int, Disc*> neighbors_type; ///< szomszédokat megadó típus (irány, pointer)
/// Tabla konstruktor
/// @param x - X méret
/// @param y - Y méret
Table(int nx = 8, int ny = 8);
/// Szomszédok lekérdezése.
/// @param x - X pozíció
/// @param y - Y pozíció
/// @return szomszédok map-je (irány, Disc*)
neighbors_type getNeighbors(int x, int y);
/// Adott irányban levő szomszéd lekérdezése
/// @param x - X pozíció
/// @param y - Y pozíció
/// @param dir - irány [0..MaxDir]
/// @return szomszéd pointere, vagy null
Disc* getNext(int x, int y, int dir) const;
/// Új pozíció létrehozása
/// @param x - X pozíció
/// @param y - Y pozíció
/// @return pozíció
Position newPosition(int x, int y) { return Position(x, y, this); }
/// Adott hely tesztelése
/// @param x - X pozíció
/// @param y - Y pozíció
/// @return true, ha szabad a hely
bool probe(int x, int y);
/// Korong felrakása a táblára
/// @param d - korong pointere
void setDisc(Disc* d);
bool jatekVege() const { return vege; }
/// Tabla kirajzolása
void list() const;
~Table();
/// Belső osztály.
/// A korongok számára nyújt általánosított pozíció információt
class Position {
friend class Table; ///< Table osztály hozzáférhet a privát adatokhoz
int x, y; ///< koordináták
Table *tp; ///< Erre a táblára hivatkozok.
int getx() const { return x; }
int gety() const { return y; }
public:
Position(int x, int y, Table* tp) :x(x), y(y), tp(tp) {}
/// Szomszédok lekérdezése.
/// @param x - X pozíció
/// @param y - Y pozíció
/// @return szomszédok map-je (irány, Disc*)
neighbors_type getNeighbors() { return tp->getNeighbors(x, y); }
/// Adott irányban levő szomszéd lekérdezése
/// @param x - X pozíció
/// @param y - Y pozíció
/// @param dir - irány [0..MaxDir]
/// @return szomszéd pointere, vagy null
Disc* getNext(int dir) { return tp->getNext(x, y, dir); }
};
};
#endif // TABLE_H
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="kiralyno" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/kiralyno" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/kiralyno" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
<Add option="-fexceptions" />
</Compiler>
<Unit filename="kiralyno.cpp" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>
/*
* Nyolc királynő probléma megoldással backtrack algoritmussal
* Okos tábla, buta királynő
*
* Ebben a példában az algoritmus fontosabb, mint OO jelleg.
*/
#include <iostream>
using std::cout;
using std::endl;
class Tabla {
bool sor[8];
bool f_atlo[15];
bool m_atlo[15];
int tab[8];
int probalkozas;
bool& Sor(int i) { return sor[i-1]; }
bool& Fo(int s, int o) { return f_atlo[s-o+7]; }
bool& Mellek(int s, int o) { return m_atlo[s+o-2]; }
int& Tab(int s) { return tab[s-1]; }
bool Szabad(int s, int o) {
return Sor(s) && Fo(s, o) && Mellek(s, o);
}
void Lefoglal(int s, int o) {
Sor(s) = Fo(s, o) = Mellek(s, o) = false;
Tab(s) = o;
}
void Felszabadit(int s, int o) {
Sor(s) = Fo(s, o) = Mellek(s, o) = true;
Tab(s) = 0;
}
public:
Tabla();
bool Probal(int oszlop);
void Rajzol(int sor, int oszlop);
};
Tabla::Tabla() {
for (int i = 0; i < 15; i++) {
f_atlo[i] = m_atlo[i] = true;
if (i < 8) {
sor[i] = true;
tab[i] = 0;
}
}
probalkozas = 0;
}
bool Tabla::Probal(int oszlop) {
int sor = 1;
bool siker = false;
do {
Rajzol(sor, oszlop);
if (Szabad(sor, oszlop)) {
Lefoglal(sor, oszlop);
if (oszlop < 8)
siker = Probal(oszlop+1);
else
siker = true;
if (!siker)
Felszabadit(sor, oszlop);
}
sor++;
} while (!siker && sor <= 8);
return siker;
}
void Tabla::Rajzol(int sor, int oszlop) {
cout.width(3);
cout << ++probalkozas << ".\n";
for (int i = 1; i <= 8; i++) {
cout.width(5);
cout << 9-i << '|';
for (int j = 1; j <= 8; j++) {
if (i == sor && j == oszlop)
cout << "?|";
else if (Tab(i) == j)
cout << "*|";
else
cout << " |";
}
cout << endl;
}
cout << " A B C D E F G H\n\n";
}
int main() {
Tabla t;
if (t.Probal(1)) {
t.Rajzol(8, 0);
cout << "Siker";
} else
cout << "Baj van";
}
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="kiralyno"
ProjectGUID="{241D3249-96E5-4995-B495-8C7AA7F19EA1}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/kiralyno.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/kiralyno.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/kiralyno.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\kiralyno.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="kiralyno2" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/kiralyno2" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/kiralyno2" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
<Add option="-fexceptions" />
</Compiler>
<Unit filename="kiralyno2.cpp" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>
/*
* Nyolc királynő probléma megoldással backtrack algoritmussal
* Buta tábla, okos királynő
*
* Ebben a példában az algoritmus fontosabb, mint OO jelleg.
*/
#include <iostream>
using std::cout;
using std::endl;
class Kiralyno {
int sor;
int oszlop;
Kiralyno *szomszed;
public:
Kiralyno(int o, Kiralyno *sz): sor(1), oszlop(o), szomszed(sz) { }
bool Utesben(int s, int o);
bool Lep();
bool Helyezkedj();
void Kiir();
};
bool Kiralyno::Utesben(int s, int o) {
int d = oszlop - o;
if (sor == s || sor + d == s || sor - d == s)
return true;
else if (szomszed != NULL)
return szomszed->Utesben(s, o);
else
return false;
}
bool Kiralyno::Lep() {
if (sor < 8) {
sor++;
return true;
}
if (szomszed != NULL) {
if (!szomszed->Lep())
return false;
if (!szomszed->Helyezkedj())
return false;
} else {
return false;
}
sor = 1;
return true;
}
bool Kiralyno::Helyezkedj() {
while (szomszed != NULL && szomszed->Utesben(sor, oszlop))
if (!Lep())
return false;
return true;
}
void Kiralyno::Kiir() {
if (szomszed != NULL)
szomszed->Kiir();
cout << (char)(oszlop-1+'A') << 9-sor << endl;
}
int main()
{
Kiralyno *babu = NULL;
for (int i = 1; i <= 8; i++) {
babu = new Kiralyno(i, babu);
babu->Helyezkedj();
}
babu->Kiir();
}
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="kiralyno2"
ProjectGUID="{68F4A1A1-6E04-41A9-8397-F843471594B1}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/kiralyno2.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/kiralyno2.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/kiralyno2.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\kiralyno2.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
#
# \file Makefile
# Makefile a labirintud programhoz
# $Id$
#
MAKEFILE=Makefile
FILES =labirintus.cpp labirint.cpp cella.cpp obj.cpp
HEADS =labirint.h cella.h obj.h
OBJS =labirintus.o labirint.o cella.o obj.o
#CXX =g++
labirint:$(OBJS)
$(CXX) $(CFLAGS) -o $@ $(OBJS)
$(OBJS): $(HEADS) $(MAKEFILE)
clean:
rm -f $(OBJS) labirint
/**
* \file cella.cpp
* cella objektum a labirintus programhoz.
* $Id: cella.cpp 499 2015-05-05 10:53:36Z szebi $
*/
#include "memtrace.h"
#include "cella.h"
/**
* Lábnyom beírása a cellába.
*/
void Cella::SetNyom(int n) { // lábnyom beirása
Labnyom lny(GetObj(), n); // lábnyom létrehozása az adott iránnyal
ny.insert(lny); // beírja a halmazba
};
/**
* Lábnyom kiolvasása a cellából.
* Adott azonosítójú nyomból kiolvassa az irányt, hogy merről jött.
*/
int Cella::GetNyom(const Obj *a) { // lábnyom kiolvasása
nyIter it = ny.find(Labnyom(a));
if (it != ny.end())
return(it->errol); // talált, erről jött utoljára.
return(-1);
};
/**
* \file cella.h
* Cella és Labnyom objektum deklarációja a labirintus programhoz.
* $Id: cella.h 499 2015-05-05 10:53:36Z szebi $
*/
#ifndef CELLA_H
#define CELLA_H
#include "obj.h"
#include <set>
/**
* Lábnyom struktúra.
* Az objektumok nyomának tárolására.
* Minden cella egy halmazban tárolja a cellába belépett objektumok nyomait.
* Objektum minden tagja publikus (struct), mivel csak egy privat halmazban fordulhat elő.
* Kezelése viszont így egyszerűbb.
*/
struct Labnyom {
const Obj *az; ///< azonosító
int errol; ///< erről jött ide
/// Konstruktor, ez a default is.
/// @param a - Nyomot hagyó objektum címe
/// @param i - irány, amerről legutóbb jött
Labnyom(const Obj *a = NULL, int i = 0)
:az(a), errol(i) {}
};
/**
* Lábnyom hasonlít.
* Összehasonlító függvény a lábnyom set számára.
* Nem az objektumokat kell hasonlítani, hanem az objektum "az" adattagját, ami
* pointer. Csak az azonosság érdeles
*/
struct Has {
bool operator()(const Labnyom& l1, const Labnyom& l2) {
return l1.az < l2.az;
}
};
/**
* Cellaobjektum.
* Ebből épül fel a labirintus.
* A 4 szomszédra pointerek mutatnak.
*/
class Cella {
int x, y; ///< geometriai koordináták
Cella *sz[4]; ///< szomszédok, ha NULL, akkor fal
Obj *p; ///< cella tartalma. URES, ha nincs rajta senki
std::set<Labnyom, Has> ny; ///< lábnyomok halmaza
typedef std::set<Labnyom, Has>::iterator nyIter;
Cella(const Cella&); // hogy ne lehessen használni
Cella& operator=(const Cella&); // hogy ne lehessen használni
public:
/// Irányok: jobbra, le, balra, fel.
/// (Kódolási trükk: a szemben levő irányok csak a 2-es bitben különböznek.
/// Ezt később kihasználjuk!
enum irany { J, L, B, F };
/// Def. konstruktor
Cella() { SetPos(0, 0); } // hogy ne maradjon inicializálatlan
/// Cella geometriai pozíciójának beállítása
/// @param i - sor koordináta
/// @param j - oszlop koordináta
void SetPos(int i, int j) { // szomszédok null értéket kapnak.
x = i; y = j; p = NULL; sz[F] = sz[L] = sz[B] = sz[J] = NULL;}
/// Szomszédság beállítása
/// @param n - irány (J, L, B, F)
/// @param cp - adott irányba eső szomszéd cella pointere
void SetSz(int n, Cella *cp) { sz[n] = cp; }// szomszéd beállítása
/// Szomszédság lekérdezése
/// @param n - irány (J, L, B, F)
/// @return - adott irányba eső szomszéd cella pointere
Cella *GetSz(int n) { return(sz[n]); } // szomszéd lekérdezése
/// Cellára objektumot tesz
/// @param a - Objektum pointere
void SetObj(Obj *a) { p = a;} // objektum beállítása
/// Cellán levő objektum lekérdezése
/// @return - Objektum pointere
Obj *GetObj() { return(p); } // objektum lekérdezése
/// Cellán levő objektum nyomának beírása a cellalistába
/// @param n - ebből az irányból lépett be a cellára
void SetNyom(int n); // lábnyom beírása
/// Objektum nyom irányának lekérdezése a cellalistából
/// @param a - objektumra mutató pointer
int GetNyom(const Obj *a); // lábnyom kiolvasása
/// Objektum nyomának kitörlése a cellalistából
void DelNyom() {ny.erase(Labnyom(GetObj()));} // lábnyom törlése
};
#endif
/**
* \file irany.h
*/
struct Irany {
/// Irányok: jobbra, le, balra, fel.
/// (Kódolási trükk: a szeben levő irányok csak a 2-es bitben különböznek.
/// Ezt később kihasználjuk!
enum irany { J, L, B, F, end } dir;
operator irany&() { return dir; }
irany next() {
if (dir < end) retrun irany(int(dir) + 1);
throw std::logic_error("Irany: hibas next");
}
irany back() {
if (dir < end) retrun irany(int(dir)^2);
throw std::logic_error("Irany: hibas back");
return dir;
}
};
/**
* \file labirint.cpp
* Labirint objektum a labirintus programhoz.
* $Id: labirint.cpp 499 2015-05-05 10:53:36Z szebi $
*/
#include <iostream>
#include "memtrace.h"
#include "labirint.h"
using std::cout;
using std::endl;
/*
* Labirint konstruktora.
* Létrehozza a cellákat és mátrix-szerűen kitölti.
*/
Labirint::Labirint(int i, int j) :n(i), m(j) {
const Cella::irany F = Cella::F; // így rövidebben tudunk rá hivatkozni
const Cella::irany J = Cella::J; // a baj az, hogy az enum nem objektum
const Cella::irany L = Cella::L; // így a using nem megy
const Cella::irany B = Cella::B;
lp = new Cella[n*m]; // terület lefoglalása
for (i = 0; i < n; i++) // feltöltés
for (j = 0; j < m; j++) {
Cella *p = &lp[I(i, j)]; // ez az aktuális cella
p->SetPos(i, j); // geometriai szomszédok
p->SetObj(&URES); // feltöltés az üres objektummal
if (i) p->SetSz(F, &lp[I(i-1, j)]); // Felső szomszéd
if (i < n-1) p->SetSz(L, &lp[I(i+1, j)]);// Alsó szomszéd
if (j) p->SetSz(B, &lp[I(i, j-1)]); // Bal szomszéd
if (j < m-1) p->SetSz(J, &lp[I(i, j+1)]);// Jobb szomszéd
}
}
/*
* Labirint Lep tagfüggvénye
* Meghívja az objektumok Lep tagfüggvényét.
* Kezeli, ha az adott ciklusban már léptetett objektum lépne újra
*/
void Labirint::Lep() {
Obj *p, *lo = NULL; // munkaváltozók
Obj **ls = new Obj*[m]; // előző sor tárolója
int i, j;
for (j = 0; j < m; j++)
ls[j] = NULL; // első sornál ez üres
try {
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
Cella &c = lp[I(i, j)];
if ((p = c.GetObj()) // Lépteti, ha nem nullpointer
&& lo != p // és, ha nem ez volt az előző
&& ls[j] != p) { // és, ha nem az előző sorból lépett ide
ls[j] = lo = p;
p->Lep(c);
}
}
}
} catch (...) { // Hiba ág: Lép dobhat kivételt, ezért a
delete[] ls; // lefoglalt területet fel kell szabadítani
throw; // és továbbdobjuk
}
// normál ág
delete[] ls; // lefoglalt területet fel kell szabadítani
}
/*
* Labirint Print tagfüggvénye.
*/
void Labirint::Print() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
Obj *p = lp[I(i, j)].GetObj(); // pointer
cout << p->Jele(); // Obj jele
}
cout << endl;
}
}
/**
* \file labirint.h
* Labirint objektum deklarációja a labirintus programhoz.
* $Id: labirint.h 499 2015-05-05 10:53:36Z szebi $
*/
#ifndef LABIRINT_H
#define LABIRINT_H
#include "cella.h"
/**
* Labirint objektum.
* A konstruktor mátrix alakban helyezi el a cellákat.
* A különleges kapcsolatokat tagfüggvényekkel kell kialakítani.
*/
class Labirint {
int n, m; ///< labirintus mérete
Cella *lp; ///< cellák tárolója
Labirint(const Labirint&); // hogy ne lehessen használni
Labirint& operator=(const Labirint&); // hogy ne lehessen használni
/// Indexelés segédfüggvénye.
/// labirintus mérete alapján kiszámítja az indexkifejezést
/// @param i - sor
/// @param j - oszlop
/// @return megfelelő cellapobjektum indexe
int I(int i, int j) { return (i * m + j); } // indexkifejezés
public:
/// Konstruktor.
/// Létrehozza a cellákat és matrix-szerüen kitölti.
/// @param i - sorok száma
/// @param j - oszlopok száma
Labirint(int i, int j); // konstruktor
/// Objektum elhelyezése.
/// Beirja az adott objektum cimét a megadott cellára
/// @param i - sor
/// @param j - oszlop
/// @param a - referencia az objektumra
void SetObj(int i, int j, Obj &a) { lp[I(i, j)].SetObj(&a); }// Obj beállítása
/// Cella objektumának lekérdezése.
/// Kiolvassa az adot cella objektumpointerét
/// @param i - sor
/// @param j - oszlop
/// @return objektum cime
Obj *GetObj(int i, int j) { return(lp[I(i, j)].GetObj()); } // Obj lekérdezése
/// Cella szomszédságának beálltása.
/// @param i - sor
/// @param j - oszlop
/// @param n - irány (J, L, B, F)
/// @param szi - somszéd sorindexe
/// @param szj - somszéd oszlopindexe
void SetSz(int i, int j, int n, int szi, int szj) { // szomszéd beállítása
lp[I(i, j)].SetSz(n, &lp[I(szi, szj)]); }
/// Cella szomszédságának lekérdezése
/// @param i - sor
/// @param j - oszlop
/// @param n - irány (J, L, B, F)
/// @return szomszédcellára mutató pointer
Cella *GetSz(int i, int j, int n) { return (lp[I(i, j)].GetSz(n)); } // szomszéd lekérdezése
/// Labirintus összes objektumának léptetése.
void Lep(); // lépteti az objektumokat
/// Labirintus "kirajzolása"
void Print(); // kirajzolja a pillanatnyi állást
~Labirint() { delete[] lp; } // destruktor
};
#endif
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="labirintus" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/labirintus" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
<Add option="-DMEMTRACE" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/labirintus" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-std=c++11" />
<Add option="-Wall" />
</Compiler>
<Unit filename="cella.cpp" />
<Unit filename="cella.h" />
<Unit filename="labirint.cpp" />
<Unit filename="labirint.h" />
<Unit filename="labirintus.cpp" />
<Unit filename="memtrace.cpp" />
<Unit filename="memtrace.h" />
<Unit filename="obj.cpp" />
<Unit filename="obj.h" />
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>
/**
* \file labirintus.cpp
* labirintus program.
* $Id: labirintus.cpp 499 2015-05-05 10:53:36Z szebi $
*/
#include <iostream>
#include <stdexcept>
#include "memtrace.h"
#include "labirint.h"
using std::cout;
using std::cin;
using std::endl;
/**
* \mainpage Labirintusban mozgó állatok modellezése
*
* \par Rövid specifikáció:
* - Tetszőleges méretű 2D labirintus definiálása.
* - Minden cellának 4 szomszédja van.
* - A logikai szomszédok nem feltétlenül egyeznek meg a geometriai szomszédokkal.
* - Alapobjektum tulajdonságai, műveletei:
* -# jel
* -# erő
* -# Néz
* -# Lép
* \par Demonstrációs cél:
* - Visszalépéses (backtrack) algoritmus bemutatása
* - Objektummodell cellás játékokhoz (ötlet).
* - Virtuális függvények használata, lényege.
* - Saját generikus lista és használata.
* \par Működés:
* - Az állatokat reprezentáló objektum a következő algoritmussal járja be a labirintust:
* - Minden cellából először jobbra, majd le, ezután balra és végül fel irányokba néz.
* - Ha az adott irányban levő cella üres, akkor belelép.
* - Ha egy cellában már van objektum, akkor az erő attribútum dönt, hogy rálép-e.
* - Minden cellában otthagyja a nyomát, azaz azt, hogy onnan merre indult legutoljára.
* - Csak olyan cellába lép be, ahol nincs saját nyoma.
* - Ha már nem tud hova lépni, visszalép.
* - Az algoritmust részletesen 12. heti előadás mutatja be
* - A fal ill. az üres cella is objektum, de nem tud lépni.
* \par Megjegyzés:
* - A Cella objektumban az irányok trükkös kódolása helyett szebb lenne egy irány objektumot
* használni. Ennek egy metódusa lehetne pl. az ellenkező irányba váltás. Ez az objektum magán belül használhatna
* bármilyen trükköt. Így a trükk nem terjedne ki más objektumokra, másrészt a Cella belső enumj-ának használata
* kényelmetlen, mivel az enum nem objektum.
* A
* \par Letölthető állományok:
* - <a href="../labirintus.cpp">labrintus.cpp</a> - főprogram fallal, egérrel, és macskával
* - <a href="../labirint.cpp">labirint.cpp</a> - labirint objektum megvalósítása
* - <a href="../cella.cpp">cella.cpp</a> - cella objektum megvalósítása
* - <a href="../obj.cpp">obj.cpp</a> - alapobjektum megvalósítása
* - <a href="../labirint.h">labirint.h</a> - labirint objektum deklarációja
* - <a href="../cella.h">cella.h</a> - cella objektum deklarációja
* - <a href="../obj.h">obj.h</a> - alapobjektum deklarációja
* - <a href="../lista.hpp">lista.hpp</a> - generikus lista a "nyom" kezeléséhez használjuk
* - <a href="../Makefile">Makefile</a> - Makefile UNIX-on történő fordításhoz
*/
/**
* Egér objektum
*/
class Eger :public Obj {
public:
char Jele() { return('e'); } // 'e'-t ad vissza
int Ereje() { return(10); } // egér ereje
void operator()(Obj *p) { // meghívódik, ha megették
cout << "Jaj szegeny " << Jele();
cout << " megetvett a(z):";
cout << p->Jele() << " jelu\n";
}
};
/**
* Macska objektum
*/
class Macska :public Obj {
const int ero;
const char jel;
public:
Macska(char j = 'm', int e = 20) :ero(e), jel(j) {}
char Jele() { return(jel); } // jele
int Ereje() { return(ero); } // macska ereje
void operator()(Obj *p) { // meghívódik, ha megették
cout << "Jaj szegeny " << Jele();
cout << " megetvett a(z):";
cout << p->Jele() << " jelu\n";
}
};
/**
* Fal objektum
*/
class Fal :public Obj {
public:
char Jele() { return('#'); } // '#'-t ad vissza
int Ereje() { return(1000); } // Fal ereje
void Lep(Cella &c) {}; // üres függvény (nem lép)
};
/**
* Demo program.
* Felépitünk egy ilyen labirintust:
* ..#..
* ...me
* #..e.
* .M...
*/
int main()
{
Labirint l(4,5); // 4 * 5 os labirintus
Eger e1, e2; // 2 egér; jele: e
Macska m1, m2('M', 21); // 2 macska; jele: m ill. M
Fal f1, f2; // 2 fal; jele: #
l.SetObj(2, 3, e1); // egér elhelyezése
l.SetObj(1, 4, e2); // egér elhelyezése
l.SetObj(1, 3, m1); // macska elhelyezése
l.SetObj(3, 1, m2); // macska elhelyezése
l.SetObj(0, 2, f1); // fal elhelyezése
l.SetObj(2, 0, f2); // fal elhelyezése
try {
char ch = '.';
l.Print();
while (ch != 'c' && cin >> std::noskipws >> ch, ch != 'e') {
l.Lep();
l.Print();
}
} catch (std::exception& e) {
cout << e.what() << endl;
}
return(0);
}
/*********************************
Memoriaszivargas-detektor
Keszitette: Peregi Tamas, BME IIT, 2011
petamas@iit.bme.hu
Kanari: Szeberenyi Imre, 2013.,
VS 2012: Szeberényi Imre, 2015.,
mem_dump: 2016.
inclue-ok: 2017., 2018. 2019.
*********************************/
#ifndef MEMTRACE_H
#define MEMTRACE_H
#if defined(MEMTRACE)
/*ha definiálva van, akkor a hibakat ebbe a fajlba írja, egyébkent stderr-re*/
/*#define MEMTRACE_ERRFILE MEMTRACE.ERR*/
/*ha definialva van, akkor futas kozben lancolt listat epit. Javasolt a hasznalata*/
#define MEMTRACE_TO_MEMORY
/*ha definialva van, akkor futas kozben fajlba irja a foglalasokat*/
/*ekkor nincs ellenorzes, csak naplozas*/
/*#define MEMTRACE_TO_FILE*/
/*ha definialva van, akkor a megallaskor automatikus riport keszul */
#define MEMTRACE_AUTO
/*ha definialva van, akkor malloc()/calloc()/realloc()/free() kovetve lesz*/
#define MEMTRACE_C
#ifdef MEMTRACE_C
/*ha definialva van, akkor free(NULL) nem okoz hibat*/
#define ALLOW_FREE_NULL
#endif
#ifdef __cplusplus
/*ha definialva van, akkor new/delete/new[]/delete[] kovetve lesz*/
#define MEMTRACE_CPP
#endif
#if defined(__cplusplus) && defined(MEMTRACE_TO_MEMORY)
/*ha definialva van, akkor atexit helyett objektumot hasznal*/
/*ajanlott bekapcsolni*/
#define USE_ATEXIT_OBJECT
#endif
/******************************************/
/* INNEN NE MODOSITSD */
/******************************************/
#ifdef NO_MEMTRACE_TO_FILE
#undef MEMTRACE_TO_FILE
#endif
#ifdef NO_MEMTRACE_TO_MEMORY
#undef MEMTRACE_TO_MEMORY
#endif
#ifndef MEMTRACE_AUTO
#undef USE_ATEXIT_OBJECT
#endif
#ifdef __cplusplus
#define START_NAMESPACE namespace memtrace {
#define END_NAMESPACE } /*namespace*/
#define TRACEC(func) memtrace::func
#include <new>
#else
#define START_NAMESPACE
#define END_NAMESPACE
#define TRACEC(func) func
#endif
// THROW deklaráció változatai
#if defined(_MSC_VER)
// VS rosszul kezeli az __cplusplus makrot
#if _MSC_VER < 1900
// * nem biztos, hogy jó így *
#define THROW_BADALLOC
#define THROW_NOTHING
#else
// C++11 vagy újabb
#define THROW_BADALLOC noexcept(false)
#define THROW_NOTHING noexcept
#endif
#else
#if __cplusplus < 201103L
// C++2003 vagy régebbi
#define THROW_BADALLOC throw (std::bad_alloc)
#define THROW_NOTHING throw ()
#else
// C++11 vagy újabb
#define THROW_BADALLOC noexcept(false)
#define THROW_NOTHING noexcept
#endif
#endif
START_NAMESPACE
int allocated_blocks();
END_NAMESPACE
#if defined(MEMTRACE_TO_MEMORY)
START_NAMESPACE
int mem_check(void);
END_NAMESPACE
#endif
#if defined(MEMTRACE_TO_MEMORY) && defined(USE_ATEXIT_OBJECT)
#include <cstdio>
START_NAMESPACE
class atexit_class {
private:
static int counter;
static int err;
public:
atexit_class() {
#if defined(CPORTA) && !defined(CPORTA_NOSETBUF)
if (counter == 0) {
setbuf(stdout, 0);
setbuf(stderr, 0);
}
#endif
counter++;
}
int check() {
if(--counter == 0)
err = mem_check();
return err;
}
~atexit_class() {
check();
}
};
static atexit_class atexit_obj;
END_NAMESPACE
#endif/*MEMTRACE_TO_MEMORY && USE_ATEXIT_OBJECT*/
/*Innentol csak a "normal" include eseten kell, kulonben osszezavarja a mukodest*/
#ifndef FROM_MEMTRACE_CPP
#include <stdlib.h>
#ifdef __cplusplus
#include <iostream>
/* ide gyűjtjük a nemtrace-vel összeakadó headereket, hogy előbb legyenek */
#include <fstream> // VS 2013 headerjében van deleted definició
#include <sstream>
#include <vector>
#include <list>
#include <map>
#include <algorithm>
#include <functional>
#endif
#ifdef MEMTRACE_CPP
namespace std {
typedef void (*new_handler)();
}
#endif
#ifdef MEMTRACE_C
START_NAMESPACE
#undef malloc
#define malloc(size) TRACEC(traced_malloc)(size,#size,__LINE__,__FILE__)
void * traced_malloc(size_t size, const char *size_txt, int line, const char * file);
#undef calloc
#define calloc(count,size) TRACEC(traced_calloc)(count, size, #count","#size,__LINE__,__FILE__)
void * traced_calloc(size_t count, size_t size, const char *size_txt, int line, const char * file);
#undef free
#define free(p) TRACEC(traced_free)(p, #p,__LINE__,__FILE__)
void traced_free(void * p, const char *size_txt, int line, const char * file);
#undef realloc
#define realloc(old,size) TRACEC(traced_realloc)(old,size,#size,__LINE__,__FILE__)
void * traced_realloc(void * old, size_t size, const char *size_txt, int line, const char * file);
void mem_dump(void const *mem, size_t size, FILE* fp);
END_NAMESPACE
#endif/*MEMTRACE_C*/
#ifdef MEMTRACE_CPP
START_NAMESPACE
#undef set_new_handler
#define set_new_handler(f) TRACEC(_set_new_handler)(f)
void _set_new_handler(std::new_handler h);
void set_delete_call(int line, const char * file);
END_NAMESPACE
void * operator new(size_t size, int line, const char * file) THROW_BADALLOC;
void * operator new[](size_t size, int line, const char * file) THROW_BADALLOC;
void * operator new(size_t size) THROW_BADALLOC;
void * operator new[](size_t size) THROW_BADALLOC;
void operator delete(void * p) THROW_NOTHING;
void operator delete[](void * p) THROW_NOTHING;
/* Visual C++ 2012 miatt kell, mert háklis, hogy nincs megfelelő delete, bár senki sem használja */
void operator delete(void *p, int, const char *) THROW_NOTHING;
void operator delete[](void *p, int, const char *) THROW_NOTHING;
#define new new(__LINE__, __FILE__)
#define delete memtrace::set_delete_call(__LINE__, __FILE__),delete
#ifdef CPORTA
#define system(...) // system(__VA_ARGS__)
#endif
#endif /*MEMTRACE_CPP*/
#endif /*FROM_MEMTRACE_CPP*/
#endif /*MEMCHECK*/
#endif /*MEMTRACE_H*/
/**
* \file obj.cpp
* Obj és URES objektumok a labirintus programhoz.
* $Id: obj.cpp 499 2015-05-05 10:53:36Z szebi $
*/
#include <stdexcept>
#include "memtrace.h"
#include "obj.h"
#include "cella.h"
/*
* Nez tagfüggvény.
* Visszaadja a paraméterként kapott cella adott
* szomszédjának típusát.
*/
Obj* Obj::Nez(int i, Cella &c, bool b) {
if (Cella *p = c.GetSz(i)) { // ha van szomszéd cella
if (b || p->GetNyom(this) < 0) // de nincs nyoma, vagy visszalép
return(p->GetObj()); // akkor az cellán álló objektum pointerét adja
}
return(NULL); // egyébként NULL-t
}
/*
* Obj Lepj tagfügvény.
* A megadott ianyba lepteti az objekumot.
*/
void Obj::Lepj(int i, Cella &c, bool b) {
if (Cella *p = c.GetSz(i)) { // szomszéd cella
p->SetObj(c.GetObj()); // beírja saját magát
if (!b) // ha nem visszalépés
p->SetNyom(ir^2); // erről jött (szemben levő irányok a 2-es bitben különböznek)
c.SetObj(&URES); // törli saját magát
}
}
/*
* Obj Lep tagfügvénye.
* Bejárásnak megfeleően lép
*/
void Obj::Lep(Cella &c) {
const Cella::irany F = Cella::F; // így rövidebben tudunk rá hivatkozni
if (c.GetNyom(this) < 0) // ha nem volt nyoma, akkor ez a kiindulási pont
c.SetNyom(F+1); // így nem tud majd innen visszalépni (F+1)
if (++ir <= F) { // ha van még bejáratlan irány
if (Obj *p = Nez(ir, c)) { // és ha van szomszéd
if (Ereje() > p->Ereje()) { // és Õ az erősebb
(*p)(this); // meghívjuk a függvényhívás operátorát
Lepj(ir, c); // rálépünk (eltapossuk)
ir = -1; // most léptünk be: kezdő irány
}
}
} else {
if ((ir = c.GetNyom(this)) > F) { // kezdő pozícióból nem tud visszalépni
throw std::logic_error("Kezdo pozicioba jutott");
} else { // visszalépés
if (Obj *p = Nez(ir, c, true)) { // lehet, hogy közben valaki odalépett, ezt ellenőrizni kell
if (Ereje() > p->Ereje()) { // Õ az erősebb
(*p)(this); // meghívjuk a függvényhívás operátorát
Lepj(ir, c, true); // visszalépünk és eltapossuk
ir ^= 2; // erre ment be (trükk: szemben levő irányok a 2-es bitben különböznek)
}
}
}
}
}
Ures URES; // Üres objektum létrehozása egyetlen példányban
/**
* \file obj.h
* Obj objektum definiciója a labirintus programhoz.
* $Id: obj.h 499 2015-05-05 10:53:36Z szebi $
*/
#ifndef OBJ_H
#define OBJ_H
#ifndef NULL
# define NULL 0 // hogy ne kelljen az iostream-et a NULL miatt include-olni
#endif
class Cella; // elődeklaráció. Azért kell, hogy az ismert legyen mint típus.
/**
* Alapobjektum .
*/
class Obj {
protected:
int ir; ///< ebbe az irányba tart most.
public:
/// Defaul konstruktor
Obj() :ir(-1) {}; // kezdő irány
/// Adott irányba "néz".
/// Adott irányban levő szomszédos cella objektumának lekérdezése
/// @param i - irány (J, L, B, F)
/// @param c - saját cellára mutató referencia
/// @param b - true, ha visszalépés, ezért önmaga nem számít
/// @return objektum pointere
Obj *Nez(int i, Cella &c, bool b = false); // szomszéd lekérdezése
/// Adott irámyba lép.
/// @param i - irány (J, L, B, F)
/// @param c - saját cellára mutató referencia
/// @param b - false: normál lépés
/// @param b - true: visszalépés
void Lepj(int i, Cella &c, bool b = false); // adott irányba lép egyet
/// Jel lekérdezése
virtual char Jele() = 0; // lekérdezi a jelét
/// Erő lekérdezése
virtual int Ereje() = 0; // lekérdezi az erejét
/// Cellán levő objektum léptetése
virtual void Lep(Cella &c); // objektumot lépteti eggyel
/// Függvényhívás operátor
virtual void operator()(Obj*) {}; // meghívódik ha az objektumot "eltaposták"
};
/**
* Üres objektum
*/
class Ures :public Obj {
public:
char Jele() { return('.'); } // '.'-t ad vissza
int Ereje() { return(0); } // ures ereje
void Lep(Cella &c) {} // léptet nem lép
};
extern Ures URES;
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment