I am doing with following code, where samosarect is one object which coming from right to left with some speed(suppose 10px per loop), tonguerect is my player's tongue which increases up to 200 width and again decreases to 0. Tongue only increases when tongue is true,tongue boolean becomes true when I press shoot button.So my problem is sometimes my player(tonguerect) don't eat(doesnt intersect with samosarect) the samosa(I watch with my eyes that rectangles are intersecting but my code is not getting that),sometimes it(intersecting with proper anim ) eats the samosa without any problem.
if (Texture.samosarect.Contains(Texture.tonguerect) || Texture.tonguerect.Intersects(Texture.samosarect) && tongue)
{
Texture.tonguerect.Y = -50;
System.Diagnostics.Debug.WriteLine("eated samosaaa");
Texture.samosarect.X = -400;
eateds = true;
jumpframe = 17;
tonguereached = true;
caught = true;
if (MainPage.togkey == 1)
eateffect.Play();
if (!catchedd)
{
score += 30; catched++; catchedd = true;
showpoint = true;
}
else { catchedd = false; }
}
For general case, this or this can help you.
Algorithm is described here.
If to talk exactly about xna, take a look here
if (ballRect.Intersects(bat1Rect))
{
ballVelo.X = Math.Abs(ballVelo.X) * -1;
}
if (ballRect.Intersects(bat2Rect))
{
ballVelo.X = Math.Abs(ballVelo.X);
}
Related
Maybe I'm not understanding the language or maybe the compiler is doing some kind of black magic but this code is not identical if I uncomment the comment which surprises me because to accept the conditional that should be the value of the variable :
`
while (distance < tMax) {
coords = uvec3(-1, -1, -1);
int active_voxel = volume_data_box_get_coords_from_point(
mi.block, first_prim_offset, mi.min.xyz, mi.max.xyz,
mi.slices_by_dimension, mi.memory_size, mi.voxel_size, hit, coords);
if ((active_voxel == 1) && (coords.x == 0) && (coords.y == 0) &&
(coords.z == 0)) {
// coords.x = 0;
// coords.y = 0;
// coords.z = 0;
bool are_extents = volume_data_box_get_extents_from_coords(
mi.block, first_prim_offset, mi.min.xyz, mi.slices_by_dimension, mi.memory_size,
mi.voxel_size, coords, voxel_extents);
if (are_extents) {
s = intersectRayOBB(ray.origin, ray.direction, mi.transform,
voxel_extents.min, voxel_extents.max);
tHit = s.t;
voxel_uv = s.uv;
hitKind = 1;
break;
}
}
// Update hit point from previous point plus direction multiplied by
// voxel size
hit += ray.direction * mi.voxel_size;
// Calculate distance between new hit point and ray origin
distance = length(hit - ray.origin);
}
`
I hope someone can clarify what is going on. Thanks!
The evaluated value is different from the expected one.
I'm trying to make a simple maze generator using the simplest algorithm I know of.
This is what my code looks like right now but there is almost never a path from start to finish and I don't know what I'm doing wrong. Here is the algorithm page
function generateMaze() {
let cells = []
for (var i=0;i<nodes.length;i++){
let cell = new Cell(nodes[i].x, nodes[i].y)
cells.push(cell)
//obstacles.push([nodes[i].x, nodes[i].y])
}
for (var i=0;i<cells.length;i++){
if (i % 2 == 0){
if (round(random(1, 2)) == 1){
obstacles.push([cells[i].x, cells[i].y-base])
}
else{
obstacles.push([cells[i].x-base, cells[i].y])
}
}
}
}
class Cell{
constructor(x, y){
this.x = x
this.y = y
this.has_visited = false
this.neigbors = []
}
}
Obstacles is just an empty array to hold the walls and base is how big each block is.
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.
I have created a Space Invaders game in which the player must shoot an asteroid which displays a random number. A sum will also be randomly generated at the start of the scene. Once the player shoots an asteroid the scene reloads, with points awarded for correct answers.
The problem I am having is that I need at least one asteroid to display the correct answer. I am currently achieving this by reloading the scene until an asteroids number matches the answer to the sum. This can take quite a few reloads and looks really bad. Is there a better way to achive this which will look better and be more efficient. I have included my effort below. I appreciate any comments. Thanks!
Script for checking the correct answer and reloading the scene.
#pragma strict
function Start ()
{
}
{
if (
Asteroid1_Script.asteroid1Value != (Sum_Script.sumA - Sum_Script.sumB) &&
Asteroid2_Script.asteroid2Value != (Sum_Script.sumA - Sum_Script.sumB) &&
Asteroid3_Script.asteroid3Value != (Sum_Script.sumA - Sum_Script.sumB) &&
Asteroid4_Script.asteroid4Value != (Sum_Script.sumA - Sum_Script.sumB) &&
Asteroid5_Script.asteroid5Value != (Sum_Script.sumA - Sum_Script.sumB)
)
{
Application.LoadLevel("L1");
}
}
Script for randomly generating the sum.
#pragma strict
static var sumA :int = 0;
static var sumB :int = 0;
function Start ()
{
var newSumA = Random.Range(6,10);
sumA = newSumA;
var newSumB = Random.Range(1,6);
sumB = newSumB;
}
function Update () {
//Question Output.
guiText.text = sumA.ToString() + " - " + sumB.ToString()+ " =";
}
Script for generating an asteroids random number.
#pragma strict
var mainCam: Camera;
static var asteroid1Value : int = 0;
var asteroid1 : Transform;
var Asteroid1Style : GUIStyle;
function Start ()
{
var newAsteroid1Value = Random.Range(0,10);
asteroid1Value = newAsteroid1Value;
asteroid1.position.x = mainCam.ScreenToWorldPoint (new Vector3 (160f, 0f, 0f)).x;
asteroid1.position.y = mainCam.ScreenToWorldPoint (new Vector3 (0f, 450f, 0f)).y;
}
function OnGUI()
{
var point = Camera.main.WorldToScreenPoint(transform.position);
GUI.Label(new Rect(point.x, Screen.currentResolution.height - point.y - 530, 110, 100), asteroid1Value.ToString(), Asteroid1Style);
}
function OnCollisionEnter(col : Collision)
{
if(asteroid1Value == (Sum_Script.sumA - Sum_Script.sumB))
{
Destroy(gameObject);
Score_Script.score ++;
}
if(asteroid1Value != (Sum_Script.sumA - Sum_Script.sumB))
{
Score_Script.score --;
}
}
Do as you are doing, generate 5 random numbers for your asteroids.
Then generate a random number between 1 and 5, this is your random asteroid, and then set its value to the answer. (sumA - sumB)
You just need to abstract your logic.
The best argument I can make is, simply put, build your random numbers before you build your asteroids.
That way, you always have a correct one.
I would simply code:
function start(){
var x = 5 //X being whatever number of asteroids you wish.
var a = new Array();
for(var i=0; i<x; i++){
a[i] = Random.Range(0,10);
}
for( i in a){ buildAsteroid(a[i]) }
}
And... if the number matches, success.
I'm using the Java2D TextLayout class together with a LineBreakMeasurer and an AttributedCharacterIterator to draw a piece of text into a box. The text is wrapped.
Profiling shows me that the code is very slow. Most of the time is lost in the method TextLayout.draw(..).
Does anyone have a suggestion for speed improvement?
// Get iterator for string
AttributedCharacterIterator iterator = attribText.getIterator();
// Create measurer
LineBreakMeasurer measurer = new LineBreakMeasurer(iterator, context);
// loop over the lines
int i = 1;
while (measurer.getPosition() < iterator.getEndIndex()) {
// Get line
TextLayout textLayout = measurer.nextLayout(w);
// get measurements
float ascent = textLayout.getAscent();
float descent = textLayout.getDescent();
float leading = textLayout.getLeading();
float size = ascent + descent;
// Move down to baseline
if( i == 1 ) {
if( coverType == CoverType.SPINE ) {
y = (box.height-size)/2;
y -= (size+leading)*(lines-1)/2;
} else if( vAlign == Alignment.Center ) {
y += (h-size)/2-(size+leading)*(lines-1)/2;
} else if( vAlign == Alignment.Bottom ) {
y += (h-size) - (size+leading)*(lines-1);
}
}
y += ascent;
// calculate starting point for alignment
float paintX = x;
switch( hAlign ) {
case Right: {
paintX = x + w - textLayout.getVisibleAdvance();
break;
}
case Center: {
paintX = x + (w - textLayout.getVisibleAdvance())/2;
break;
}
}
// Draw line
textLayout.draw(g2d, paintX, y);
// Move down to top of next line
y += descent + leading;
i++;
}
The relevant code snippet is shown above. attribText is an AttributtedString set before. context is the g2d.getFontRenderContext().
This post is rather old now so I hope you have found a solution that works for your needs. If you haven't here is something to think about. You only need to draw the text that is within the visible region. Since you know the y coordinate of each line it is easy to check to see if the y lies within the bounds of getVisibleRect(). Only painting the text that is necessary greatly improves performance (assuming of course that your text is longer than a single page).