From 138474be6a43bcea84fa4d14404213178258e27c Mon Sep 17 00:00:00 2001 From: Monty Galloway <21006694@student.uwa.edu.au> Date: Wed, 28 May 2014 12:56:00 +0800 Subject: [PATCH 1/3] halfway working limited dfs --- in/M1.txt | 2 +- include/threes_AI.h | 6 +- include/threes_Mechanics.h | 31 ++- threes | Bin 121500 -> 146684 bytes threes.cpp | 15 +- threes_AI.cpp | 495 +++++++++++++++++++++++++++++++++++-- 6 files changed, 528 insertions(+), 21 deletions(-) diff --git a/in/M1.txt b/in/M1.txt index 56b4547..d0b0f8d 100755 --- a/in/M1.txt +++ b/in/M1.txt @@ -71,4 +71,4 @@ L U R U -R +R \ No newline at end of file diff --git a/include/threes_AI.h b/include/threes_AI.h index f447329..241277f 100644 --- a/include/threes_AI.h +++ b/include/threes_AI.h @@ -11,6 +11,10 @@ /* dfs on board for move path */ std::vector dfs(Board &); -int greedy_search(Board &, int, int); +Direction greedy_search2(Board, int); +Direction greedy_search(Board, int); +// int greedy_search(Board &, int, int); +int a_star(Board, std::vector &, int, int *); +int i_aStar(Board &, std::vector &); #endif \ No newline at end of file diff --git a/include/threes_Mechanics.h b/include/threes_Mechanics.h index a6124ba..07d9dd3 100644 --- a/include/threes_Mechanics.h +++ b/include/threes_Mechanics.h @@ -53,23 +53,48 @@ class comparator { /** Board data structure **/ typedef std::vector< std::vector > Board; -typedef std::priority_queue, std::vector >, comparator> PQ; +typedef std::priority_queue, std::vector >, comparator> PQ; /** Node for DFS tree **/ struct Node { PQ poss_moves; Node *parent; + // the direction moved to get from parent-->node + Direction moveMade; Board b; int depth; + int f; + int g; + int h; + int score; + // unique identifier for comparing nodes + int id; + std::string str; + bool isRoot; }; +class nodeComparator { + bool reverse; +public: + nodeComparator(const bool & revparam=false) { + reverse=revparam; + } + + bool operator() (const Node &n1, const Node &n2) { + if (reverse) return n1.f < n2.f; + return n2.f < n1.f; + } +}; + +typedef std::priority_queue, nodeComparator> NodeQ; + /** * data structure to represent shift. */ struct Shift { int id; // describes the row/col that was shifted (id in [0-3]) Direction m; // determines if id is row or col (D/U: col, L/R: row) - // string representation of shift - allows lexicographic sorting of shifts + // representation of shift row/col - allows lexicographic sorting of shifts std::vector string_vec; // constructor @@ -117,7 +142,7 @@ int tileMove(int *, int *); */ void setShiftString(Board &, Shift &); -/* Get legal moves on board given input tile */ +/* Get legal moves on board given tileNum to refer to tile in sequence */ std::vector getPossibleMoves(const Board &, int); PQ getPossibleMovesSorted(const Board &, int); diff --git a/threes b/threes index 111766a618d1f1b15024ccc1672dabd5deb8d31b..c3def09372e4a05dc690b8116aa5d765e27fa615 100755 GIT binary patch literal 146684 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

mr` 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 diff --git a/threes.cpp b/threes.cpp index 30db4b4..f9e9393 100644 --- a/threes.cpp +++ b/threes.cpp @@ -38,10 +38,12 @@ int iterateMoves(Board &board, switch (playType) { case MAN: { // user defined input determines moves std::cin >> move; + if (move == "Q") return -1; while (move_parse.count(move) == 0) { std::cout << "Move \"" << move << "\" invalid, please enter from {U, L, D, R}:\n"; std::cin >> move; + if (move == "Q") return -1; if (std::cin.eof()) { std::cout << "Read EOF for stdin.. Ending game.\n"; return -1; @@ -57,6 +59,10 @@ int iterateMoves(Board &board, m = poss_moves[rand_move]; break; } + case AI:{ + m = greedy_search2(board,tile_num); + break; + } default: { printf("Invalid playType used. Please use those defined in threes.h\n"); exit(EXIT_FAILURE); @@ -137,6 +143,7 @@ int main(int argc, char *argv[]) { std::srand(std::time(NULL)); int endGame = -1; + switch (playType) { // play the game how user wants to case (MAN): endGame = iterateMoves(board, move_sequence, MAN); @@ -147,7 +154,13 @@ int main(int argc, char *argv[]) { case (AI): // not implemented yet, call to AI algorithm goes here, // endGame = AI(); or something - return 1; + // endGame = dfs(board, move_sequence, 4); + // int maxDepth; + // endGame = a_star(board, move_sequence, &maxDepth); + // endGame = i_aStar(board, move_sequence); + endGame = iterateMoves(board, move_sequence, AI); + break; + // return 1; default: return help(); } diff --git a/threes_AI.cpp b/threes_AI.cpp index 9cccd9c..1811c4d 100644 --- a/threes_AI.cpp +++ b/threes_AI.cpp @@ -1,9 +1,272 @@ #include -void hillClimb(Board &board) { - PQ moveQueue; - +/* Setup move parser maps, mapping Direction to string and vice versa */ +void initMoveParsers(std::map &move_parse, + std::map &parse_move) { + + move_parse.insert(std::pair("U", U)); + move_parse.insert(std::pair("D", D)); + move_parse.insert(std::pair("L", L)); + move_parse.insert(std::pair("R", R)); + + parse_move.insert(std::pair(U, "U")); + parse_move.insert(std::pair(D, "D")); + parse_move.insert(std::pair(L, "L")); + parse_move.insert(std::pair(R, "R")); +} + +std::string dToStr(Direction d) { + switch (d) { + case U: + return "U"; + case D: + return "D"; + case L: + return "L"; + case R: + return "R"; + default: + std::cout << "Error in dToStr\n"; + exit(EXIT_FAILURE); + } +} + +Direction strToD(std::string str) { + std::map move_parse; + move_parse.insert(std::pair("U", U)); + move_parse.insert(std::pair("D", D)); + move_parse.insert(std::pair("L", L)); + move_parse.insert(std::pair("R", R)); + + return move_parse.find(str)->second; +} +/* Greedy best first search hill climb. Selects next move based on highest + * board score +// */ +// void hillClimb(Board &board) { +// PQ moveQueue; +// // std::vector parents = std::vector(inputSequence.size()); +// std::vector possMoves = getPossibleMoves(board, tile_num); + +// for (Direction d : possMoves) { +// moveQueue.push() +// } + +// while (!moveQueue.empty()) { + +// } +// } + +/* calculates number of tiles that merged in move from board1 -> board2, returns + * 0 if no tiles were consumed in the move (i.e. an input tile was added) + */ +int numberCollapsed(Board &b1, Board &b2) { + + int numNonZeroB1 = 0; + int numNonZeroB2 = 0; + + for (int row = 0; row < BOARD_SIZE; row++) { + for (int col = 0; col < BOARD_SIZE; col++) { + numNonZeroB1 += b1[row][col] > 0 ? 1 : 0; + numNonZeroB2 += b2[row][col] > 0 ? 1 : 0; + } + } + + return std::max(numNonZeroB1 - numNonZeroB2, 0); +} + +int nonZeroTiles(Board &b) { + int numNonZero = 0; + + for (int row = 0; row < BOARD_SIZE; row++) { + for (int col = 0; col < BOARD_SIZE; col++) { + numNonZero += b[row][col] > 0 ? 1 : 0; + } + } + return numNonZero; } + +std::string boardToString(Board &b) { + std::string str = ""; + + for (int row = 0; row < BOARD_SIZE; row++) { + for (int col = 0; col < BOARD_SIZE; col++) { + str += std::to_string(b[row][col]); + } + } + return str; +} + +int THEORETICAL_HIGHSCORE; +int a_star(Board board, std::vector &move_sequence, int depth, int *moves) { + // goal state is tile_num = inputSequence.size() - 1 + // f(n) = 1 (cost of adding tile) + number of tiles collapsed? + int maxDepth = 0; + std::map move_parse; + std::map parse_move; + initMoveParsers(move_parse, parse_move); + + std::map parentMap; + + Node root; + root.parent = NULL; + root.b = board; + root.depth = tile_num; + root.f = 0; + root.id = 0; + root.score = score(root.b); + root.str = boardToString(root.b); + // getPossibleMoves(root.b, root.depth); + + parentMap.insert(std::pair(root.str, root)); + std::vector parents = std::vector(depth); + NodeQ nq; + nq.push(root); + Node *maxNode; + int maxScore = -1; + while (!nq.empty()) { + Node top = nq.top(); nq.pop(); + // std::cout << top.score << "\n"; + // std::cout << top.f << "\n"; + // if (top.depth == inputSequence.size() - 1) { // depth limit to # input tiles + if (top.depth - root.depth == depth) { // depth limit to # input tiles + if (top.score > maxScore) { + // *moves = top.depth; + maxScore = top.score; + // move_sequence[top.depth] = parse_move.find(top.moveMade)->second; + // maxDepth = top.depth; + maxNode = ⊤ + // std::cout << "Yo\n"; + } + continue; + } + + maxDepth = std::max(maxDepth, top.depth - tile_num); + // store move sequence unless we have root node, which will + // have no previous move + // if (top.id != root.id) { + // move_sequence[top.depth] = parse_move.find(top.moveMade)->second; + // } + + // get frontier of current node + std::vector possMoves = getPossibleMoves(top.b, top.depth); + + if (possMoves.size() == 0) { + // if (parentMap.size() > 0) + // parentMap.erase(parentMap.find(top.str)); + continue; + } + // std::cout << top.depth << "\n"; + int id = 0; + for (Direction d: possMoves) { // push moves as nodes to queue + Node n; + n.b = top.b; + n.id = top.id + 1 + id++; + n.depth = top.depth + 1; + makeMove(&n.b, d, n.depth); // make move + n.parent = ⊤ + n.moveMade = d; + n.score = score(n.b); + n.g = top.g + 1; + // n.h = std::pow(numberCollapsed(top.b, n.b), 2); // this is where the heuristic matters + // n.h = std::pow(nonZeroTiles(n.b), 2); + // n.h = 0; // uniform cost search + // n.h = n.score; + // n.h = nonZeroTiles(n.b); + // n.h = score(n.b); + // std::cout << n.h << "\n"; + // n.f = std::max(n.h + n.g, top.f); + // n.f = std::min(n.h + n.g, top.f); + n.f = score(n.b); // greedy best first search + n.str = boardToString(n.b); + // std::cout << n.depth - root.depth -1 << "\n"; + parents[n.depth - root.depth - 1] = top; + + // if (parentMap.count(n.str) == 0) + // parentMap.insert(std::pair(n.str, top)); + // else { + // if (parentMap.find(n.str)->second.f > n.f) { + // parentMap.erase(parentMap.find(n.str)); + // parentMap.insert(std::pair(n.str, top)); + // } + // } + nq.push(n); + } + // std::cout << parentMap.size() << "\n"; + } + *moves = maxDepth; + // std::cout << "max: " << maxDepth << "\n"; + // make the actual moves on the initial board + // for (int i = 1; i < *moves; i++) { + // std::cout << move_sequence[i]; + // makeMove(&board, move_parse.find(move_sequence[i])->second, i); + // // printBoard(board); + // } + // Node p = *maxNode; + int mm = maxDepth; + // std::cout << "mm " << mm << "\n"; + while (mm > 0) { + Node p = parents[mm--]; + move_sequence.push_back(parse_move.find(p.moveMade)->second); + } + + // while (p.str != root.str) { + // // std::cout << parse_move.find(p.moveMade)->second; + // p = parentMap.find(p.str)->second; + // } + // parentMap.clear(); + std::reverse(move_sequence.begin(), move_sequence.end()); + std::cout <<"move_sequence.size(): " << move_sequence.size() << "\n"; + // std::vector movess; + // while (p->parent != NULL) { + // // printBoard(p.b); + // std::cout << parse_move.find(p->moveMade)->second; + // // makeMove(&board, p.moveMade) + // p = p->parent; + // } + + std::cout << "\n"; + + return !(tile_num < inputSequence.size() - 1); +} + +int i_aStar(Board &board, std::vector &move_sequence) { + THEORETICAL_HIGHSCORE = inputSequence.size()*inputSequence.size(); + // THEORETICAL_HIGHSCORE = 1; + + std::cout << "Goal: " << THEORETICAL_HIGHSCORE << "\n"; + std::map move_parse; + std::map parse_move; + initMoveParsers(move_parse, parse_move); + int numMoves = 0; + int DEPTH_LIMIT = 8; + + // a_star(board, move_sequence, DEPTH_LIMIT, &numMoves); + // int tt = 0; + // for (std::string s: move_sequence) { + // makeMove(&board, move_parse.find(s)->second, tt++); + // } + // return 0; + // std::vector allMoves; + while (numMoves < inputSequence.size()) { + std::vector ms; + // std::cout << score(board) << "\n"; + int moves = 0; + a_star(board, ms, DEPTH_LIMIT, &moves); + numMoves += ms.size(); + if (ms.size() == 0) break; + for (int i = 0; i < ms.size(); i++) { + move_sequence.push_back(ms[i]); + makeMove(&board, move_parse.find(ms[i])->second, tile_num++); + printBoard(board); + } + // tile_num += moves; + } + std::cout << "inputSequence.size(): " << inputSequence.size() << "\n"; + std::cout << "moves: " << numMoves << "\n"; + return !(numMoves < inputSequence.size()); +} + /* * * Design Possibilities: @@ -24,7 +287,12 @@ void hillClimb(Board &board) { // priorty_queue poss_moves // Node *parent // } -std::vector dfs(Board &board) { +int dfs(Board &board, std::vector move_sequence, int depthLimit) { + // Use these maps to convert strings to Direction enums, and vice versa. + + + move_sequence = std::vector(inputSequence.size()); + std::vector parents = std::vector(inputSequence.size()); Node root; root.b = board; @@ -44,7 +312,7 @@ std::vector dfs(Board &board) { max_score = std::max(score(top.b), max_score); continue; } - + if (top.depth == depthLimit) continue; PQ poss_moves = getPossibleMovesSorted(top.b, top.depth + 1); if (poss_moves.size() == 0) continue; @@ -59,19 +327,216 @@ std::vector dfs(Board &board) { } } - std::cout << max_score << "\n"; - return parents; + return 0; } -int greedy_search(Board &board, int depth, int tile) { - if (depth == 0) return score(board); +// int depthLimitedDFSSearch(Board board, int depth) { +// std::stack path; +// std::stack frontier; + +// Node root; +// root.b = board; +// root. +// } + +// int greedy_search(Board &board, int depth, int tile) { +// if (depth == 0) return score(board); +// std::vector poss_moves = getPossibleMoves(board, tile); +// if (poss_moves.size() == 0) return score(board); +// int best_val = -1; +// for (Direction m : poss_moves) { +// Board b = board; +// makeMove(&b, m, tile); // possibly add shifts # to eval total +// best_val = std::max(best_val, greedy_search(b, depth - 1, (tile + 1) % (inputSequence.size() - 1))); +// } +// return best_val; +// } +// +// + +Direction greedy_search2(Board board, int tile) { + // std::vector poss_moves = getPossibleMoves(board, tile); + + int depthLim = 3; + + std::stack ns; + + Node root; + // root.parent = NULL; + root.b = board; + // root.moveMade = NULL; + root.depth = 0; + root.score = score(board); + root.isRoot = true; + ns.push(root); + + Node maxNode = root; + + while (!ns.empty()) { + Node top = ns.top(); ns.pop(); + + std::vector possMoves = getPossibleMoves(top.b, tile); + + if (top.depth == depthLim) { + if (maxNode->score < top.score) { + maxNode = top; + printBoard(maxNode->b); + } + continue; + } + for (Direction d : possMoves) { + Node n; + n.b = top.b; + makeMove(&n.b, d, tile); + + n.moveMade = d; + n.depth = top.depth + 1; + n.score = score(n.b); + n.parent = ⊤ + n.isRoot = false; + ns.push(n); + } + + tile++; + } + std::cout << "Printing:\n"; + printBoard(maxNode->b); + std::cout << "Printing:\n"; + printBoard(maxNode->parent->b); + std::cout << "Root: \n"; + printBoard(root.b); + exit(0); + + Node *p = maxNode; + + std::stack moveStack; + + // while (!p->isRoot) { + for (int i = 0; i < depthLim; i++) { + moveStack.push(p->moveMade); + std::cout << dToStr(p->moveMade) << "\n"; + p = p->parent; + } + + Direction m; + while (moveStack.size() > 1) { + m = moveStack.top(); + std::cout << dToStr(moveStack.top()); + moveStack.pop(); + } + std::cout << "\n"; + return m; +} + +Direction greedy_search(Board board, int tile){ std::vector poss_moves = getPossibleMoves(board, tile); - if (poss_moves.size() == 0) return score(board); - int best_val = -1; + int sss = 0; + int tile1 = tile + 1; + int tile2 = tile1 + 1; + int tile3 = tile2 + 1; + int tile4 = tile3 + 1; + int tile5 = tile4 + 1; + int tile6 = tile5 + 1; + int tile7 = tile6 + 1; + Direction ddd; for (Direction m : poss_moves) { - Board b = board; - makeMove(&b, m, tile); // possibly add shifts # to eval total - best_val = std::max(best_val, greedy_search(b, depth - 1, (tile + 1) % (inputSequence.size() - 1))); + std::vector< std::vector > b_copy = board; + makeMove(&b_copy, m, tile); + std::vector poss_moves1 = getPossibleMoves(b_copy, tile1); + if(poss_moves1.size()==0){ + if(score(b_copy)>sss){ + sss = score(b_copy); + ddd = m; + printf("Direction : %i \n", ddd); + } + continue; + } + for(Direction n : poss_moves1) { + std::vector< std::vector > c_copy = b_copy; + makeMove(&c_copy, n, tile1); + std::vector poss_moves2 = getPossibleMoves(c_copy, tile2); + if(poss_moves2.size()==0){ + if(score(c_copy)>sss){ + sss = score(c_copy); + ddd = m; + printf("Direction : %i \n", ddd); + } + continue; + } + for(Direction l : poss_moves2) { + std::vector< std::vector > d_copy = c_copy; + makeMove(&d_copy, l, tile2); + std::vector poss_moves3 = getPossibleMoves(d_copy, tile3); + if(poss_moves3.size()==0){ + if(score(d_copy)>sss){ + sss = score(d_copy); + ddd = m; + printf("Direction : %i \n", ddd); + } + continue; + } + for(Direction k : poss_moves3) { + std::vector< std::vector > e_copy = d_copy; + makeMove(&e_copy, k, tile3); + std::vector poss_moves4 = getPossibleMoves(e_copy, tile4); + if(poss_moves4.size()==0){ + if(score(e_copy)>sss){ + sss = score(e_copy); + ddd = m; + printf("Direction : %i \n", ddd); + } + continue; + } + for(Direction j : poss_moves4) { + std::vector< std::vector > f_copy = e_copy; + makeMove(&f_copy, j, tile4); + std::vector poss_moves5 = getPossibleMoves(f_copy, tile5); + if(poss_moves5.size()==0){ + if(score(f_copy)>sss){ + sss = score(f_copy); + ddd = m; + printf("Direction : %i \n", ddd); + } + continue; + } + for(Direction o : poss_moves5) { + std::vector< std::vector > g_copy = f_copy; + makeMove(&g_copy, o, tile5); + std::vector poss_moves6 = getPossibleMoves(g_copy, tile6); + if(poss_moves6.size()==0){ + if(score(g_copy)>sss){ + sss = score(g_copy); + ddd = m; + printf("Direction : %i \n", ddd); + } + continue; + } + for(Direction p : poss_moves6) { + std::vector< std::vector > h_copy = g_copy; + makeMove(&h_copy, p, tile6); + std::vector poss_moves7 = getPossibleMoves(h_copy, tile7); + if(poss_moves7.size()==0){ + if(score(h_copy)>sss){ + sss = score(h_copy); + ddd = m; + printf("Direction : %i \n", ddd); + } + continue; + } + for(Direction q : poss_moves7) { + std::vector< std::vector > i_copy = h_copy; + makeMove(&i_copy, q, tile7); + if(score(i_copy)>sss){ + sss = score(i_copy); + ddd = m; + } + } + } + } + } + } + } + } } - return best_val; + return ddd; } From cb5b23b7c4dd906f46b91ad0cc760213836510d2 Mon Sep 17 00:00:00 2001 From: Monty Galloway <21006694@student.uwa.edu.au> Date: Wed, 28 May 2014 12:57:11 +0800 Subject: [PATCH 2/3] halfway working limited dfs --- threes_AI.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/threes_AI.cpp b/threes_AI.cpp index 1811c4d..b77807a 100644 --- a/threes_AI.cpp +++ b/threes_AI.cpp @@ -399,13 +399,13 @@ Direction greedy_search2(Board board, int tile) { tile++; } - std::cout << "Printing:\n"; - printBoard(maxNode->b); - std::cout << "Printing:\n"; - printBoard(maxNode->parent->b); - std::cout << "Root: \n"; - printBoard(root.b); - exit(0); + // std::cout << "Printing:\n"; + // printBoard(maxNode->b); + // std::cout << "Printing:\n"; + // printBoard(maxNode->parent->b); + // std::cout << "Root: \n"; + // printBoard(root.b); + // exit(0); Node *p = maxNode; From ce1d2656a8ac956ae18cde4ea4a815e178e47bb3 Mon Sep 17 00:00:00 2001 From: Monty Galloway <21006694@student.uwa.edu.au> Date: Wed, 28 May 2014 13:47:52 +0800 Subject: [PATCH 3/3] working but bad LDFS --- include/threes_Mechanics.h | 2 +- threes | Bin 146684 -> 150788 bytes threes_AI.cpp | 115 ++++++++++++++++++++----------------- 3 files changed, 62 insertions(+), 55 deletions(-) diff --git a/include/threes_Mechanics.h b/include/threes_Mechanics.h index 07d9dd3..7152d5d 100644 --- a/include/threes_Mechanics.h +++ b/include/threes_Mechanics.h @@ -58,7 +58,7 @@ typedef std::priority_queue, std::vectornode Direction moveMade; Board b; diff --git a/threes b/threes index c3def09372e4a05dc690b8116aa5d765e27fa615..dd2225bdd669cad088374f26eb552eb941df2fcd 100755 GIT binary patch delta 20689 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 IL4PRxA9P+1R{#J2 delta 20521 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 S=0g6Clsm)A;||l4^Zy?nPK%EK diff --git a/threes_AI.cpp b/threes_AI.cpp index b77807a..78d4bfa 100644 --- a/threes_AI.cpp +++ b/threes_AI.cpp @@ -357,48 +357,55 @@ int dfs(Board &board, std::vector move_sequence, int depthLimit) { Direction greedy_search2(Board board, int tile) { // std::vector poss_moves = getPossibleMoves(board, tile); - int depthLim = 3; - - std::stack ns; - - Node root; - // root.parent = NULL; - root.b = board; - // root.moveMade = NULL; - root.depth = 0; - root.score = score(board); - root.isRoot = true; - ns.push(root); - - Node maxNode = root; - - while (!ns.empty()) { - Node top = ns.top(); ns.pop(); - - std::vector possMoves = getPossibleMoves(top.b, tile); - - if (top.depth == depthLim) { - if (maxNode->score < top.score) { - maxNode = top; - printBoard(maxNode->b); + int depthLim = 2; + + // Node maxNode = root; + int maxScore = score(board); + std::vector originalFrontier = getPossibleMoves(board, tile); + Direction maxD = originalFrontier[0]; + + if (originalFrontier.size() == 1) return maxD; // no point doing dfs + + for (Direction od : originalFrontier) { + Node root; + root.b = board; + makeMove(&root.b, od, tile); + int tileID = tile; + root.score = score(board); + root.depth = 0; + std::stack ns; + ns.push(root); + while (!ns.empty()) { + Node top = ns.top(); ns.pop(); + + std::vector possMoves = getPossibleMoves(top.b, tileID); + + if (top.depth == depthLim) { + if (maxScore < top.score) { + maxScore = top.score; + maxD = od; + // std::cout << "maxNode board, move is: " << dToStr(maxNode.moveMade) << "\n"; + // printBoard(maxNode.b); + } + continue; + } + for (Direction d : possMoves) { + Node n; + n.b = top.b; + makeMove(&n.b, d, tileID); + + n.moveMade = d; + n.depth = top.depth + 1; + n.score = score(n.b); + n.parent = ⊤ + // n.isRoot = false; + ns.push(n); } - continue; - } - for (Direction d : possMoves) { - Node n; - n.b = top.b; - makeMove(&n.b, d, tile); - n.moveMade = d; - n.depth = top.depth + 1; - n.score = score(n.b); - n.parent = ⊤ - n.isRoot = false; - ns.push(n); + tileID++; } - - tile++; } + return maxD; // std::cout << "Printing:\n"; // printBoard(maxNode->b); // std::cout << "Printing:\n"; @@ -407,25 +414,25 @@ Direction greedy_search2(Board board, int tile) { // printBoard(root.b); // exit(0); - Node *p = maxNode; + // Node *p = &maxNode; - std::stack moveStack; + // std::stack moveStack; - // while (!p->isRoot) { - for (int i = 0; i < depthLim; i++) { - moveStack.push(p->moveMade); - std::cout << dToStr(p->moveMade) << "\n"; - p = p->parent; - } + // // while (!p->isRoot) { + // for (int i = 0; i < depthLim; i++) { + // moveStack.push(p->moveMade); + // std::cout << dToStr(p->moveMade) << "\n"; + // p = p->parent; + // } - Direction m; - while (moveStack.size() > 1) { - m = moveStack.top(); - std::cout << dToStr(moveStack.top()); - moveStack.pop(); - } - std::cout << "\n"; - return m; + // Direction m; + // while (moveStack.size() > 1) { + // m = moveStack.top(); + // std::cout << dToStr(moveStack.top()); + // moveStack.pop(); + // } + // std::cout << "\n"; + // return m; } Direction greedy_search(Board board, int tile){