A name for this primitive operation? - animation

I use this function a lot in game/graphics programming.
float slide(float from, float to, float by) {
float difference = to - from;
if(difference > by) {
return from + by;
} else if(difference < -by) {
return from - by;
} else {
return to;
}
}
The basic idea is "move towards so-and-so by this much".
I've called it slide because if you call it each frame on something's position, it appears as sliding with constant speed towards a target position.
Any other suggestions for naming?

I think slide is OK, maybe moveTo or floatTo would be also OK.
And one more idea. when you use this function like this:
Slide(0, 5, 10);
(menaing that "by" is bigger than possible step)
and you'll call it several times, the object will oscilate around "to" position.
You should add some handling for it. Like:
float slide(float from, float to, float by) {
float difference = to - from;
if(difference > by && from + by < to) {
return from + by;
} else if(difference < -by && from - by > to) {
return from - by;
} else {
return to;
}
}
hope this will help.

Related

I cannot get operator+ function to compile, have I maybe made a mistake with one of the constructors?

This operator will receive a string with the format "x,y."
x represents an x coordinate and y represents a y coordinate. If the
coordinates are valid (that is within the valid range of the chess
board) then the appropriate variables should be set with these
variables. If the coordinates are invalid,
then nothing should happen.
operator<<: It also prints out (with a new line at the end), a message in the
following format:
b rook at [0,0]
The side is printed first, then the piece type followed by the coordinates at the end.
``This message must be sent to the output variable.
Piece::Piece(){
}
Piece::Piece(Piece *newPiece){
*newPiece = Piece;
}
Piece::Piece(string pType, char side, int x, int y){
//string pT = pType;
//char s = side;
}
Piece::~Piece(){
}
char Piece::getSide(){
return side;
}
string Piece::getPieceType(){
return PieceType;
}
int Piece::getX(){
return xPos;
}
int Piece::getY(){
return yPos;
}
void Piece::setX(int x){
xPos = x;
}
void Piece::setY(int y){
yPos = y;
}
void Piece::operator[](int pos){
cin>>pos;
if(pos != 0 || pos != 1){
cout<<"Invalid Index"<<endl;
}
else{
if(pos == 0 ){
cout<<"x coord"<<xPos;
}
if(pos == 1){
cout<<"y cord"<<yPos;
}
}
}
//Everything above compiled
Piece& Piece::operator+(string move){
if(xPos<=side && yPos<=side){
move = xPos;",";yPos;
return move;
}
return 0;
}
ostream& Piece::operator<<(ostream& output,const Piece& t ){
t = Piece;
output = side + PieceType + pos;
cout<<output;
}
There is no reason to call new inside the constructor.
Since you're calling new Piece in the constructor of Piece, you will end up in an infinite loop. The expression new Piece again invokes the constructor of Piece, which again calls new Piece, which invokes the constructor, ...
Also, think a second about what's happening here: *newPiece = new Piece; is constructing a new Piece object and assigning the result to the local pointer value newPiece. After the constructor ends (which in your case, it never does, because of the infinite loop), that local variable goes out of scope and your new Piece is lost.

Matrix Text rain effect in Processing 3.3

I'm working on making a matrix text rain effect in Processing 3.3 as a simple starter project for learning the processing library and Java. My code so far:
class Symbol {
int x, y;
int switchInterval = round(random(2, 50));
float speed;
char value;
Symbol(int x, int y, float speed) {
this.x = x;
this.y = y;
this.speed = speed;
}
//Sets to random symbol based on the Katakana Unicode block
void setToRandomSymbol() {
if(frameCount % switchInterval == 0) {
value = char((int) random(0x30A0, 0x3100));
}
}
//rains the characters down the screen and loops them to the top when they
// reach the bottom of the screen
void rain() {
if(y <= height) {
y += speed;
}else {
y = 0;
}
}
}
Symbol symbol;
class Stream {
int totalSymbols = round(random(5, 30));
Symbol[] symbols = new Symbol[500];
float speed = random(5, 20);
//generates the symbols and adds them to the array, each symbol one symbol
//height above the one previous
void generateSymbols() {
int y = 0;
int x = width / 2;
for (int i = 0; i <= totalSymbols; i++) {
symbols[i] = new Symbol(x, y, speed);
symbols[i].setToRandomSymbol();
y -= symbolSize;
}
}
void render() {
for(Symbol s : symbols) {
fill(0, 255, 70);
s.setToRandomSymbol();
text(s.value, s.x, s.y);
s.rain();
}
}
}
Ok, so that was a lot of code, Let me explain my dilemma. The issue I'm having is that when I run the code I get a NullpointerException at the s.setToRandomSymbol(); method call in the for each loop in the render function. The weird part about this NullPointerException error and the part I'm not understanding is that it's being thrown on a method that doesn't take in any arguments that could be coming back empty, and the method itself is void, so it shouldn't be returning anything, right? Why is this returning Null and what did I do wrong to have it return this way?
First you come up with a random number betwen 5 and 30:
int totalSymbols = round(random(5, 30));
Then you create an array that holds 500 instances of your Symbol class:
Symbol[] symbols = new Symbol[500];
Note that this array holds 500 null values at this point.
Then you add a maximum of 30 instances of Symbol to your array:
for (int i = 0; i <= totalSymbols; i++) {
symbols[i] = new Symbol(x, y, speed);
Note that this array now holds at least 470 null values at this point.
Then you iterate over all 500 indexes:
for(Symbol s : symbols) {
s.setToRandomSymbol();
But remember that at least 470 of these indexes are null, which is why you're getting a NullPointerException.
Some basic debugging would have told you all of this. I would have started by adding a basic println() statement just before you get the error:
for(Symbol s : symbols) {
println("s: " + s);
s.setToRandomSymbol();
This would have showed you that you're iterating over null values.
Anyway, to fix your problem you need to stop iterating over your entire array, or you need to stop making room for indexes you never use.
In the future, please try to narrow your problem down to a MCVE before posting. Note that this much smaller example program shows your error:
String[] array = new String[10];
array[0] = "test";
for(String s : array){
println(s.length());
}

Othello Minimax Algorithm

I am trying to implement an artificial intelligence player for Othello using the Minimax algorithm. The computer plays decently, but its not great. Did I implement it correctly in my following code?
Coordinate bestCoordinate = null;
public int minimax(MyButton[][] gameBoard, int depth, boolean maximizingPlayer) {
if (depth == 0) {
return evaluateBoard(gameBoard);
}
if (maximizingPlayer) {
int bestValue = Integer.MIN_VALUE;
LinkedList<Coordinate> moves = generateMoves(gameBoard);
for (Coordinate move : moves) {
MyButton[][] newBoard = cloneBoard(gameBoard);
processMove(newBoard, newBoard[move.getxCoordinate()][move.getyCoordinate()]);
int v = minimax(newBoard, depth - 1, !maximizingPlayer);
if (v > bestValue) {
bestValue = v;
bestCoordinate = move;
}
}
return bestValue;
}
else {
int bestValue = Integer.MAX_VALUE;
LinkedList<Coordinate> moves = generateMoves(gameBoard);
for (Coordinate move : moves) {
MyButton[][] newBoard = cloneBoard(gameBoard);
processMove(newBoard, newBoard[move.getxCoordinate()][move.getyCoordinate()]);
int v = minimax(newBoard, depth - 1, !maximizingPlayer);
if (v < bestValue) {
bestValue = v;
bestCoordinate = move;
}
}
return bestValue;
}
}
Also, here is my evaluation function:
public int evaluateBoard(MyButton[][] gameBoard) {
int blackPieces = 0;
int whitePiecess = 0;
for (MyButton[] array : gameBoard) {
for (MyButton button : array) {
if (button.getBackground().equals(Color.black)) {
blackPieces++;
} else if (button.getBackground().equals(Color.WHITE)) {
whitePiecess++;
}
}
}
int cornerBonus = 10;
if (gameBoard[0][0].getBackground().equals(Color.BLACK)) {
blackPieces += cornerBonus;
}
if (gameBoard[0][getBoardWidth() - 1].getBackground().equals(Color.BLACK)) {
blackPieces += cornerBonus;
}
if (gameBoard[getBoardHeight() - 1][0].getBackground().equals(Color.BLACK)) {
blackPieces += cornerBonus;
}
if (gameBoard[getBoardHeight() - 1][getBoardWidth() - 1].getBackground().equals(Color.BLACK)) {
blackPieces += cornerBonus;
}
if (gameBoard[0][0].getBackground().equals(Color.WHITE)) {
whitePiecess += cornerBonus;
}
if (gameBoard[0][getBoardWidth() - 1].getBackground().equals(Color.WHITE)) {
whitePiecess += cornerBonus;
}
if (gameBoard[getBoardHeight() - 1][0].getBackground().equals(Color.WHITE)) {
whitePiecess += cornerBonus;
}
if (gameBoard[getBoardHeight() - 1][getBoardWidth() - 1].getBackground().equals(Color.WHITE)) {
whitePiecess += cornerBonus;
}
return whitePiecess - blackPieces;
}
(The computer always plays white, and the human is black).
I'm mainly unsure because the computer doesn't seem to protect corners, despite the bonus points that they give. Is there anything wrong with my code/logic?
You are updating your best move at each depth. Make a constant called SEARCH_DEPTH outside of your function that you use every time you call the function and do an if check:
if(depth == SEARCH_DEPTH) {
bestCoordinate = move;
}
Also, assuming you are the maximizing player, you only want to set the move in the if(maximizingPlayer) block.
I did not test your code out myself, but that is the minimax algorithm, and it appears to be written correctly (assuming your helper functions are implemented correctly). I have some points that might give you insight as to why your agent is not acting optimally:
I see your objective function is the number of pieces your agent has minus the number the opponent has, plus a bonus for corner pieces. This might seem like the best strategy, but I would read up on how good Othello players make their moves. Often, they try to flip only one piece if they can until late game, as they have more opportunities that way.
Minimax won't necessarily return the moves that will lead to capturing corners, even if you weigh them highly, because it might be undermined by the opponent's choice of moves. For example, lets say your algorithm looks three turns ahead on the computer's turn, so it first looks at a state where it capture a corner with a high objective function. However, your opponent will be choosing the route that will minimize your objective function, and as such the computer will not view moves moving towards capturing a corner piece as optimal because of the risk. I don't know how easy this will be, but if you can somehow visualize the tree, you might be able to figure out if this is the case.

Find the maximum height they can make by standing on each other?

Weights of n men and their strengths (max weight they can carry) are given. Height of all are same and given. Find the maximum height they can make by standing on each other?
That means, you have to place them by taking maximum number of men from them, such that no men is carrying weight more than his strength.
This question is bugging me. First I thought using greedy, by taking person of maximum strength first, but it is not giving correct answer. Then I tried to solve it, like knapsack, which is also not right. I am not able to come up with an efficient algorithm. Can anyone help?
First of all sorry by my english :)
Here is one way that you can think as a way to solve the problem.
Ok if you can supposed that each floor absorbs the whole weight in a uniform form, ( I mean there are no restriction like "one man can carry only the weight of two mens" or somethin like that..).
We will start with an hypothetical structure which has one man for each floor, and with that structure we will start to check the restrictions and arrange people.
We will check the lowest floor (first floor), and we will ask: Can this floor handle the weight of all the higher floors?
If the answer is no, we remove one men from the top of the tower and we add it to this floor, and we check again the weight condition on this floor.
If the answer is yes, we pass to check the next floor.
After that we will have an structure which meet the requirements.
And the C# code:
int amountOfMens = n;
float weight = w;
float strength = s;
float height = h;
int []mensInEachFloor;
public void MyAlg()
{
mensInEachFloor = new int[ amountOfMens ]; // the max height that we can achieve is the max amount of mens.
for(int i=0; i < mensInEachFloor.Length; i++ )
{
// we put one men on each floor, just to check if the highest heigth is achivable
mensInEachFloor[i] = 1;
}
// now we start to use our algorithm
// for each floor:
for(int i = 0; i < mensInEachFloor.Length; i++ )
{
// for each floor we will work on it until supports its designed weight
bool floorOk = false;
while(! floorOk)
{
// we check if the weigth of all the higher floors can be supported by this level
float weightToBeSupported = TotalWeightOfHigherFloors(i+1);
float weightThatCanBeSupported = WeightHandledByFloor(i);
if( weightToBeSupported > weightThatCanBeSupported )
{
// Remove one men from the top
RemoveOneManFromHighestFloor();
// add one men to this floor to help with the weight
AddOneManToFloor(i);
}
else
{
// we are ok on this floor :)
floorOk = true;
}
}
}
Debug.Log("The total heigth of the tower is : " + GetTowerHeight() );
}
private float TotalWeightOfHigherFloors(int startingFloor)
{
float totalWeight = 0;
for(int i= startingFloor; i< mensInEachFloor.Length; i++ )
{
totalWeight += mensInEachFloor[i] * weight;
}
return totalWeight;
}
private float WeightHandledByFloor(int floor)
{
return mensInEachFloor[floor] * strength;
}
private void RemoveOneManFromHighestFloor()
{
// we start to see from the top..
for(int i = mensInEachFloor.Length - 1 ; i >= 0; i-- )
{
// if on this floor are one or more mens..
if(mensInEachFloor[i] != 0)
{
// we remove from the floor
mensInEachFloor[i] = mensInEachFloor[i] - 1;
// and we are done
break;
}
}
}
private void AddOneManToFloor(int floor)
{
// Add one man to the selected floor
mensInEachFloor[floor] = mensInEachFloor[floor] + 1;
}
private float GetTowerHeight()
{
// We will count the number of floors with mens on it
float amountOfFloors = 0;
for(int i= 0; i< mensInEachFloor.Length; i++ )
{
// If there are more than zero mens
if( mensInEachFloor[i] > 0 )
{
// it means that it is a valid floor
amountOfFloors++;
}
}
// number of floors times height
return amountOfFloors * height;
}
Cheers !

Score in processing

Hello I want to create a catch game in processing.
I added a score counter but it does not work properly.
When I catch the object I want the score to go up with 1.
If it touches the ground -5. The problem is that when it hit the ground the score still goes up with 1. anyone an idea? this is the class of the object:
class Burger {
int breedte;
int hoogte;
float snelheid;
float x ;
float y;
Burger() {
x = random(0,1000);
}
void run() {
display();
testBurger();
}
void display() {
img1.resize(60,60);
image(img1,x,y);
}
void testBurger() {
y = y+richting;
if(y > 800){
x = random(0,1000);
println(score);
}
if(y > 600 && mouseX -90 < x && mouseX +90 > x){
score = score+1;
y = -400;
x = random(0,1000);
}
}
}
There are a lot of "magic numbers" in this code (see http://en.wikipedia.org/wiki/Magic_number_%28programming%29 for why this is poor practice) but if I'm following correctly, then I think you have your signs the wrong way around.
You currently test if(y > 800){ which would mean that that Burger object is near the bottom of the screen (remember, y-axis starts from 0 at the TOP of screen). I suggest you rather test if (y < 800) for the "catching" condition, and then you can simply use } else { at the end for the "hit the bottom of the screen" condition.

Resources