Skip to content

Commit

Permalink
feat(catchthecat): add automated tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tolstenko committed Sep 12, 2023
1 parent 69cb3ee commit 1819997
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 9 deletions.
3 changes: 2 additions & 1 deletion courses/artificialintelligence/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ endfunction()
add_subdirectory(assignments/flocking)
add_subdirectory(assignments/maze)
add_subdirectory(assignments/life)
add_subdirectory(assignments/rng)
add_subdirectory(assignments/rng)
add_subdirectory(assignments/catchthecat)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
add_executable(ai-catchthecat simulator.cpp Catcher.h Cat.h)

file(GLOB TEST_INPUT_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tests/*.in)
file(GLOB TEST_OUTPUT_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tests/*.out)

add_custom_test(ai-catchthecat-test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ai-catchthecat "${TEST_INPUT_FILES}" "${TEST_OUTPUT_FILES}")
8 changes: 8 additions & 0 deletions courses/artificialintelligence/assignments/catchthecat/Cat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once
#include "IAgent.h"

struct Cat : public IAgent {
std::pair<int,int> move(const std::vector<bool>& world, std::pair<int,int> catPos, int sideSize ) override{
return {0,0}; // todo: change this
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once
#include "IAgent.h"

struct Catcher : public IAgent {
std::pair<int,int> move(const std::vector<bool>& world, std::pair<int,int> catPos, int sideSize ) override{
return {0,0}; // todo: change this
}
};
19 changes: 19 additions & 0 deletions courses/artificialintelligence/assignments/catchthecat/IAgent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once
#include <vector>
#include <utility>
#include <string>

// NO NOT CHANGE THIS FILE
struct IAgent {
public:
/**
* @brief the agent implementation. the center of the world is {0,0}, top left is {-sideSize/2, -sideSize/2} and the bottom right is {sideSize/2, sideSize/2}.
*
* @param world the world as a vector of booleans. true means there is a wall, false means there is no wall. The vector is the linearization of the matrix of the world.
* @param catPos the position of the cat in the world {x,y} relative to the center of the world.
* @param sideSize the side size of the world. it will be always a square that follows the sequence of 4*i+1: 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, ...
*
* @return the position to move to {x,y}. relative to the center of the world.
*/
virtual std::pair<int,int> move(const std::vector<bool>& world, std::pair<int,int> catPos, int sideSize ) = 0;
};
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ compose final report of the run
### IAgent.h

```cpp title="IAgent.h"
#pragma once
#include <vector>
#include <utility>
#include <string>

// NO NOT CHANGE THIS FILE
struct IAgent {
Expand All @@ -135,12 +135,5 @@ public:
* @return the position to move to {x,y}. relative to the center of the world.
*/
virtual std::pair<int,int> move(const std::vector<bool>& world, std::pair<int,int> catPos, int sideSize ) = 0;

/**
* @brief the name of the agent. it will be used to identify the agent in the ranking.
*
* @return the name of the agent. Follow this pattern: "CAT_<username>" or "Cat_<username>_<modifier>" if you have more than one Cat; "CATCHER_<username>" or "Catcher_<username>_<modifier>" if you have more than one Catcher.
*/
virtual std::string name() = 0;
};
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// DO NOT SUBMIT THIS FILE
// IMPROVE THIS SIMULATOR FOR YOUR OWN USE
// this code is not well tested, use as entry point for your own simulator
#include <iostream>
#include <vector>
#include "Cat.h"
#include "Catcher.h"

void print(const std::vector<bool>& state, int sideSize, std::pair<int,int> catPos, char turn) {
std::cout << turn << " " << sideSize << " " << catPos.first << " " << catPos.second << std::endl;
catPos.first += sideSize/2;
catPos.second += sideSize/2;
auto catPosIndex = catPos.second * sideSize + catPos.first;
for(int y=0; y<sideSize; y++) {
if (y % 2 == 1) std::cout << ' ';
for (int x = 0; x < sideSize; x++) {
if(y * sideSize + x == catPosIndex) {
std::cout << 'C';
} else
std::cout << (state[y * sideSize + x] ? '#' : '.');
if (x < sideSize - 1) std::cout << ' ';
}
std::cout << std::endl;
}
}

std::vector<bool> readBoard(int sideSize) {
std::vector<bool> board;
board.reserve(sideSize*sideSize);
for(int i=0; i<sideSize*sideSize; i++) {
char c;
std::cin >> c;
switch (c) {
case '#':
board.push_back(true);
break;
case '.':
case 'C':
board.push_back(false);
break;
default:
i--;
break;
}
}
return board;
}

int main() {
char turn;
int sideSize;
int catX, catY;
std::vector<bool> blocked;
std::cin >> turn >> sideSize >> catX >> catY;
blocked = readBoard(sideSize);
if(turn == 'C'){
Cat cat;
auto catMove = cat.move(blocked, {catX, catY}, sideSize);
print(blocked, sideSize, {catMove.first, catMove.second}, 'T');
} else {
Catcher catcher;
auto catcherMove = catcher.move(blocked, {catX, catY}, sideSize);
blocked[(catcherMove.second + sideSize/2) * sideSize + catcherMove.first+sideSize/2] = true;
print(blocked, sideSize, {catX, catY}, 'C');
}
}
Empty file.
Empty file.

0 comments on commit 1819997

Please sign in to comment.