Overhaul makefile, pass random variables by reference to avoid recreating
This commit is contained in:
parent
010a9188a6
commit
6e83262859
4 changed files with 226 additions and 175 deletions
57
Makefile
57
Makefile
|
@ -1,24 +1,69 @@
|
||||||
TARGET = A1
|
TARGET = A1
|
||||||
SRC_FILES = main.cpp hands.cpp
|
SRC_FILES = main.cpp hands.cpp
|
||||||
|
|
||||||
# NO EDITS BELOW THIS LINE
|
# Tyler's custom makefile extensions
|
||||||
CXX = g++ -g
|
.DEFAULT_GOAL := all # Necessary so `make` doesn't run the "pack" target, as it is declared before "all"
|
||||||
|
.PHONY: pack clean-run c run
|
||||||
|
|
||||||
|
## Adds only the necessary files for build into a .tar.gz file, named appropriately
|
||||||
|
ARCHIVED_FILES = Makefile $(SRC_FILES) $(SRC_FILES:.cpp=.h) $(SRC_FILES:.cpp=.hpp)
|
||||||
|
pack:
|
||||||
|
tar --ignore-failed-read -czvf $(TARGET).tar.gz $(shell echo $(ARCHIVED_FILES) | xargs ls -d 2>/dev/null)
|
||||||
|
|
||||||
|
## Runs the pack target and then attempts to build & run the program to make sure it functions correctly
|
||||||
|
pack-test: pack
|
||||||
|
$(eval TMP := $(shell mktemp -d))
|
||||||
|
tar -xvzf $(TARGET).tar.gz --directory $(TMP)
|
||||||
|
make -C $(TMP)
|
||||||
|
$(TMP)/$(TARGET)
|
||||||
|
rm -rf $(TMP)
|
||||||
|
|
||||||
|
## An extension of the clean command that is shorter to type and removes a potential .tar.gz file
|
||||||
|
c: clean
|
||||||
|
$(DEL) -f $(TARGET).tar.gz
|
||||||
|
|
||||||
|
## Simply builds and then executes the program
|
||||||
|
run: all
|
||||||
|
./$(TARGET)
|
||||||
|
|
||||||
|
# NO EDITS NEEDED BELOW THIS LINE
|
||||||
|
|
||||||
|
CXX = g++
|
||||||
|
CXXFLAGS = -O2
|
||||||
|
CXXFLAGS_DEBUG = -g
|
||||||
|
CXXFLAGS_WARN = -Wall -Wextra -Wunreachable-code -Wshadow -Wpedantic
|
||||||
|
CPPVERSION = -std=c++17
|
||||||
|
|
||||||
OBJECTS = $(SRC_FILES:.cpp=.o)
|
OBJECTS = $(SRC_FILES:.cpp=.o)
|
||||||
|
|
||||||
ifeq ($(shell echo "Windows"), "Windows")
|
ifeq ($(shell echo "Windows"), "Windows")
|
||||||
TARGET := $(TARGET).exe
|
TARGET := $(TARGET).exe
|
||||||
DEL = del
|
DEL = del
|
||||||
|
Q =
|
||||||
else
|
else
|
||||||
DEL = rm -f
|
DEL = rm -f
|
||||||
|
Q = "
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
$(TARGET): $(OBJECTS)
|
$(TARGET): $(OBJECTS)
|
||||||
$(CXX) -std=c++17 -o $@ $^
|
$(CXX) -o $@ $^
|
||||||
|
|
||||||
%.o: %.cpp
|
.cpp.o:
|
||||||
$(CXX) -std=c++17 -o $@ -c $<
|
$(CXX) $(CXXFLAGS) $(CPPVERSION) $(CXXFLAGS_DEBUG) $(CXXFLAGS_WARN) -o $@ -c $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(DEL) $(TARGET) $(OBJECTS)
|
$(DEL) -f $(TARGET) $(OBJECTS) Makefile.bak
|
||||||
|
|
||||||
|
depend:
|
||||||
|
@sed -i.bak '/^# DEPENDENCIES/,$$d' Makefile
|
||||||
|
@$(DEL) sed*
|
||||||
|
@echo $(Q)# DEPENDENCIES$(Q) >> Makefile
|
||||||
|
@$(CXX) -MM $(SRC_FILES) >> Makefile
|
||||||
|
|
||||||
|
.PHONY: all clean depend
|
||||||
|
|
||||||
|
# DEPENDENCIES
|
||||||
|
main.o: main.cpp hands.h
|
||||||
|
hands.o: hands.cpp hands.h
|
||||||
|
|
49
hands.cpp
49
hands.cpp
|
@ -1,6 +1,5 @@
|
||||||
#include "hands.h"
|
#include "hands.h"
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
@ -30,11 +29,9 @@ std::unique_ptr<Hand> Hand::fromChar(const char letter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Hand> Hand::generateRandom() {
|
std::unique_ptr<Hand>
|
||||||
std::mt19937 mt(
|
Hand::generateRandom(std::mt19937 &mt,
|
||||||
std::chrono::steady_clock::now().time_since_epoch().count());
|
std::uniform_int_distribution<int> &intDist) {
|
||||||
std::uniform_int_distribution<int> intDist(0, 4);
|
|
||||||
|
|
||||||
switch (intDist(mt)) {
|
switch (intDist(mt)) {
|
||||||
case 0:
|
case 0:
|
||||||
return std::make_unique<Rock>();
|
return std::make_unique<Rock>();
|
||||||
|
@ -60,58 +57,68 @@ std::string Rock::getHandName() const { return "rock"; }
|
||||||
GameResult Rock::compareAgainst(const Hand &other) {
|
GameResult Rock::compareAgainst(const Hand &other) {
|
||||||
const std::string otherName = other.getHandName();
|
const std::string otherName = other.getHandName();
|
||||||
|
|
||||||
if (otherName == "rock")
|
if (otherName == "rock") {
|
||||||
return GameResult::Tie;
|
return GameResult::Tie;
|
||||||
if (otherName == "scissors" || otherName == "lizard")
|
}
|
||||||
|
if (otherName == "scissors" || otherName == "lizard") {
|
||||||
return GameResult::Win;
|
return GameResult::Win;
|
||||||
else
|
} else {
|
||||||
return GameResult::Loss;
|
return GameResult::Loss;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string Paper::getHandName() const { return "paper"; }
|
std::string Paper::getHandName() const { return "paper"; }
|
||||||
GameResult Paper::compareAgainst(const Hand &other) {
|
GameResult Paper::compareAgainst(const Hand &other) {
|
||||||
const std::string otherName = other.getHandName();
|
const std::string otherName = other.getHandName();
|
||||||
|
|
||||||
if (otherName == "paper")
|
if (otherName == "paper") {
|
||||||
return GameResult::Tie;
|
return GameResult::Tie;
|
||||||
if (otherName == "rock" || otherName == "spock")
|
}
|
||||||
|
if (otherName == "rock" || otherName == "spock") {
|
||||||
return GameResult::Win;
|
return GameResult::Win;
|
||||||
else
|
} else {
|
||||||
return GameResult::Loss;
|
return GameResult::Loss;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string Scissors::getHandName() const { return "scissors"; }
|
std::string Scissors::getHandName() const { return "scissors"; }
|
||||||
GameResult Scissors::compareAgainst(const Hand &other) {
|
GameResult Scissors::compareAgainst(const Hand &other) {
|
||||||
const std::string otherName = other.getHandName();
|
const std::string otherName = other.getHandName();
|
||||||
|
|
||||||
if (otherName == "scissors")
|
if (otherName == "scissors") {
|
||||||
return GameResult::Tie;
|
return GameResult::Tie;
|
||||||
if (otherName == "paper" || otherName == "lizard")
|
}
|
||||||
|
if (otherName == "paper" || otherName == "lizard") {
|
||||||
return GameResult::Win;
|
return GameResult::Win;
|
||||||
else
|
} else {
|
||||||
return GameResult::Loss;
|
return GameResult::Loss;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string Lizard::getHandName() const { return "lizard"; }
|
std::string Lizard::getHandName() const { return "lizard"; }
|
||||||
GameResult Lizard::compareAgainst(const Hand &other) {
|
GameResult Lizard::compareAgainst(const Hand &other) {
|
||||||
const std::string otherName = other.getHandName();
|
const std::string otherName = other.getHandName();
|
||||||
|
|
||||||
if (otherName == "lizard")
|
if (otherName == "lizard") {
|
||||||
return GameResult::Tie;
|
return GameResult::Tie;
|
||||||
if (otherName == "spock" || otherName == "paper")
|
}
|
||||||
|
if (otherName == "spock" || otherName == "paper") {
|
||||||
return GameResult::Win;
|
return GameResult::Win;
|
||||||
else
|
} else {
|
||||||
return GameResult::Loss;
|
return GameResult::Loss;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string Spock::getHandName() const { return "spock"; }
|
std::string Spock::getHandName() const { return "spock"; }
|
||||||
GameResult Spock::compareAgainst(const Hand &other) {
|
GameResult Spock::compareAgainst(const Hand &other) {
|
||||||
const std::string otherName = other.getHandName();
|
const std::string otherName = other.getHandName();
|
||||||
|
|
||||||
if (otherName == "spock")
|
if (otherName == "spock") {
|
||||||
return GameResult::Tie;
|
return GameResult::Tie;
|
||||||
if (otherName == "scissors" || otherName == "rock")
|
}
|
||||||
|
if (otherName == "scissors" || otherName == "rock") {
|
||||||
return GameResult::Win;
|
return GameResult::Win;
|
||||||
else
|
} else {
|
||||||
return GameResult::Loss;
|
return GameResult::Loss;
|
||||||
}
|
}
|
||||||
|
}
|
12
hands.h
12
hands.h
|
@ -1,5 +1,8 @@
|
||||||
|
#ifndef HANDS_H
|
||||||
|
#define HANDS_H
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
enum GameResult { Win, Tie, Loss };
|
enum GameResult { Win, Tie, Loss };
|
||||||
|
|
||||||
|
@ -7,8 +10,9 @@ class Hand {
|
||||||
public:
|
public:
|
||||||
// Converts a user-inputted character to the correct instance of Hand.
|
// Converts a user-inputted character to the correct instance of Hand.
|
||||||
static std::unique_ptr<Hand> fromChar(char);
|
static std::unique_ptr<Hand> fromChar(char);
|
||||||
// Randomly returns one of the variants of Hand.
|
// Randomly returns one of the variants of Hand, as generated by a Mersenne
|
||||||
static std::unique_ptr<Hand> generateRandom();
|
// Twister function seeded by the current unix time
|
||||||
|
static std::unique_ptr<Hand> generateRandom(std::mt19937&, std::uniform_int_distribution<int>&);
|
||||||
|
|
||||||
// Returns the lowercase name of this type of hand, for example "rock" or
|
// Returns the lowercase name of this type of hand, for example "rock" or
|
||||||
// "scissors".
|
// "scissors".
|
||||||
|
@ -20,6 +24,8 @@ class Hand {
|
||||||
virtual GameResult compareAgainst(const Hand &) = 0;
|
virtual GameResult compareAgainst(const Hand &) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// List of all types of RPSLS hands that can be played
|
||||||
|
|
||||||
class Rock : public Hand {
|
class Rock : public Hand {
|
||||||
public:
|
public:
|
||||||
std::string getHandName() const override;
|
std::string getHandName() const override;
|
||||||
|
@ -49,3 +55,5 @@ class Spock : public Hand {
|
||||||
std::string getHandName() const override;
|
std::string getHandName() const override;
|
||||||
GameResult compareAgainst(const Hand &) override;
|
GameResult compareAgainst(const Hand &) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // HANDS_H
|
||||||
|
|
53
main.cpp
53
main.cpp
|
@ -1,6 +1,13 @@
|
||||||
/* CSCI 200: Assignment 1 (Rock Paper Scissors): Tyler Beckman
|
/* CSCI 200: Assignment 1 (Rock Paper Scissors): Tyler Beckman
|
||||||
*
|
*
|
||||||
* Author: Tyler Beckman
|
* Author: Tyler Beckman
|
||||||
|
* Resources used:
|
||||||
|
* While learning how to use classes & polymorphism in the way I wanted to,
|
||||||
|
* student Maxwell Gross helped me debug why the way I was trying to use classes
|
||||||
|
* didn't work (virtual fields not existing, where I needed to put class
|
||||||
|
* definitions vs method definitions, etc). No code was copied or written for
|
||||||
|
* me, he just helped me understand how all of these structures I was used to in
|
||||||
|
* other langs like Java and JS worked in cpp :)
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* A C++ program to play rock paper scissors (lizard spock) against
|
* A C++ program to play rock paper scissors (lizard spock) against
|
||||||
|
@ -15,30 +22,13 @@
|
||||||
* multiple other languages, so I felt it would be fun to use this as an excuse
|
* multiple other languages, so I felt it would be fun to use this as an excuse
|
||||||
* to learn how the concepts work in cpp. I apologize if this is more
|
* to learn how the concepts work in cpp. I apologize if this is more
|
||||||
* complicated than we were supposed to make it, but it was fun and it should
|
* complicated than we were supposed to make it, but it was fun and it should
|
||||||
* still be a perfectly functional and point-scoring program :)
|
* still be a perfectly functional and point-scoring program :). To clarify, I
|
||||||
*
|
* didn't copy any code but I did use multiple online tutorials and references
|
||||||
* Academic integrity:
|
* to learn how classes and the such work in cpp.
|
||||||
* 1. Because I did go overboard on making an object-oriented program when we
|
|
||||||
* haven't even learned how classes yet, I did use a lot of online cpp syntax
|
|
||||||
* reference and explainers to learn how classes and inheritance work in cpp.
|
|
||||||
* This includes mainly cppreference.com, but also geeksforgeeks.org and
|
|
||||||
* tutorialspoint to figure out the basics. Nowhere did I actually copy the
|
|
||||||
* exact structures, I simply used it to figure out how to do what I wanted and
|
|
||||||
* what I knew how to do in other languages such as Java and JavaScript (have a
|
|
||||||
* "which one wins" function on each sibling class of "Hand"). I am not entirely
|
|
||||||
* sure if this needs cited, but given we have learned none of this yet, I just
|
|
||||||
* wanted to clarify that this is all my code - not copied from the internet,
|
|
||||||
* ChatGPT, Copilot, or anything else other than my code.
|
|
||||||
* 2. Also since I was making a program with structures that I hadn't quite
|
|
||||||
* learned in this language yet, I did ask Max[TODO FILL IN NAME] (someone with
|
|
||||||
* experience in cpp) for debugging assistance when concepts I was used to in
|
|
||||||
* other languages didn't work well in cpp. For example, I wasn't used to class
|
|
||||||
* definitions and function bodies being separate, so he helped me figure out
|
|
||||||
* the correct structure there so I could properly reference sibling classes in
|
|
||||||
* methods on the parent class.
|
|
||||||
*/
|
*/
|
||||||
#include "hands.h"
|
#include "hands.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
@ -48,6 +38,9 @@ int main(void) {
|
||||||
int losses = 0;
|
int losses = 0;
|
||||||
int ties = 0;
|
int ties = 0;
|
||||||
|
|
||||||
|
std::mt19937 mt(std::chrono::steady_clock::now().time_since_epoch().count());
|
||||||
|
std::uniform_int_distribution<int> intDist(0, 4);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Take a letter input and convert it to the correct class type for
|
// Take a letter input and convert it to the correct class type for
|
||||||
// later use
|
// later use
|
||||||
|
@ -59,12 +52,12 @@ int main(void) {
|
||||||
const std::unique_ptr<Hand> userHand = Hand::fromChar(handLetter);
|
const std::unique_ptr<Hand> userHand = Hand::fromChar(handLetter);
|
||||||
|
|
||||||
// Generate a random "computer" hand and display the two choices
|
// Generate a random "computer" hand and display the two choices
|
||||||
const std::unique_ptr<Hand> computerHand = Hand::generateRandom();
|
const std::unique_ptr<Hand> computerHand =
|
||||||
|
Hand::generateRandom(mt, intDist);
|
||||||
|
|
||||||
std::cout << std::endl
|
std::cout << std::endl
|
||||||
<< "Player chose " << userHand->getHandName() << std::endl
|
<< "Player chose " << userHand->getHandName() << std::endl
|
||||||
<< "Computer chose " << computerHand->getHandName()
|
<< "Computer chose " << computerHand->getHandName() << std::endl
|
||||||
<< std::endl
|
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
// Compare the two hands, add to statistics, and give the correct output
|
// Compare the two hands, add to statistics, and give the correct output
|
||||||
|
@ -78,14 +71,13 @@ int main(void) {
|
||||||
break;
|
break;
|
||||||
case Tie:
|
case Tie:
|
||||||
std::cout << "No one wins, as " << userHand->getHandName()
|
std::cout << "No one wins, as " << userHand->getHandName()
|
||||||
<< " is the same as " << computerHand->getHandName()
|
<< " is the same as " << computerHand->getHandName() << "."
|
||||||
<< "." << std::endl;
|
<< std::endl;
|
||||||
ties++;
|
ties++;
|
||||||
break;
|
break;
|
||||||
case Loss:
|
case Loss:
|
||||||
std::cout << "The computer wins, as "
|
std::cout << "The computer wins, as " << computerHand->getHandName()
|
||||||
<< computerHand->getHandName() << " beats "
|
<< " beats " << userHand->getHandName() << "." << std::endl;
|
||||||
<< userHand->getHandName() << "." << std::endl;
|
|
||||||
losses++;
|
losses++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -105,8 +97,7 @@ int main(void) {
|
||||||
std::cout << std::endl
|
std::cout << std::endl
|
||||||
<< "Thanks for playing!" << std::endl
|
<< "Thanks for playing!" << std::endl
|
||||||
<< "You won " << wins << " game(s), lost " << losses
|
<< "You won " << wins << " game(s), lost " << losses
|
||||||
<< " game(s), and tied " << ties << " time(s)."
|
<< " game(s), and tied " << ties << " time(s)." << std::endl;
|
||||||
<< std::endl;
|
|
||||||
std::exit(0);
|
std::exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue