Check of checkmate in chess - algorithm

I am using this object oriented design of chess. I have implemented generating of valid moves for all pieces. Now I am trying implement check of checkmate.
I tried to make a method, which if player have moves, which cancel the checkmate. But the program end with StackOverflowError.
I delete the method. But the pseudoalgorithm of the method was something like that
boolean isGameOver(arg){
if(playerIsInCheck){
if(!hasValidMoves){
print("checkmate");
return true;
}
else{
return false;
}
}
else{
if(!hasValidMoves){
print("stalemate");
return true;
}
else{
return false;
}
}
}
I don't know how to check if the move cancel the checkmate. Can anyone advise me? I do not need all the code written in any programming language. Pseudoalgorithm will be sufficient.

The algorithm for checking for checkmate is as follows:
public boolean checkmated(Player player) {
if (!player.getKing().inCheck() || player.isStalemated()) {
return false; //not checkmate if we are not
//in check at all or we are stalemated.
}
//therefore if we get here on out, we are currently in check...
Pieces myPieces = player.getPieces();
for (Piece each : myPieces) {
each.doMove(); //modify the state of the board
if (!player.getKing().inCheck()) { //now we can check the modified board
each.undoMove(); //undo, we dont want to change the board
return false;
//not checkmate, we can make a move,
//that results in our escape from checkmate.
}
each.undoMove();
}
return true;
//all pieces have been examined and none can make a move and we have
//confimred earlier that we have been previously checked by the opponent
//and that we are not in stalemate.
}

I can't tell you why you are getting a stack overflow without seeing your method definitions, but I can explain how you check for mate-cancelling moves ( no pseudocode, sorry).
Basically, you generate a List of all possible Moves (Pseudolegals) and you let your programm try each of them. If the players king is no longer hittable in the resulting position (in your case you use the IsInCheck method), the current move is cancelling the mate.
If you do need the pseudocode, write a comment and I'll see what I can do.

Related

Cant make jump in gamemaker studio2

I can't make the jump work in my game made in game maker studio 2
this project uses gravity and the game maker's language.
this is now just random words so stack overflow lets me post this question so Minecraft is a cool game :).
here is the code:
/// #description this is the create event
// You can write your code in this editor
sprite_index=Sprite1;
image_speed = 1;
image_index = 0;
step event:
/// #description Insert description here
// You can write your code in this editor
#region //gravedad
if place_free(x,y+1){
gravity =1;
}else{
gravity=0;
}
if vspeed >=20{vspeed=20}
#endregion
#region //movimiento
if keyboard_check(ord("D")){
direction=0
speed = brr;
}
else{
speed=0;
}
if keyboard_check(ord("A")){
direction=180
speed = brr;
}
if keyboard_check_pressed(vk_space) && !place_free(x,y+1){
vspeed = -broo;
}
#endregion
I think the !place_free(x,y+1) is the problem here
if keyboard_check_pressed(vk_space) && !place_free(x,y+1){
vspeed = -broo;
}
Assuming place_free checks if there's no collision, it may either be a case of setting the origin point of the player object to the bottom center, or not having a solid instance or collision mask. (as seen in the manual)
I personally prefer using place_meeting to check on collisions with a specific object, and ignore the requirements needed for place_free to work, maybe that could work better for you.

Unity 2D: NullReferenceException. How to add two manager scripts?

I am quite new to Unity, so please bear with my horrible explanation. I have followed a tutorial on youtube about a 2D fighting game: https://www.youtube.com/watch?v=n8S3WgVoOmo&t=3319s
I will provide my code below.
In the linked video, the video-maker makes one PlayerManager script which controls both my player and duplicates of my player. Through a simple AI, the duplicate becomes my enemy and we fight. This much works as expected.
Now I wanted to change it a bit like a 2D platformer. I took the PlayerManager and split it into two. AIManager (same code as in tutorial overall) and a PlayerManager with some changes. This also worked well and I am able to move and the AI also recognises me. The problem comes from a script called DamageScript. It recognizes if and when I take damage, and triggers the relevant animation.
When the DamageScript was connected to just the PlayerManager, when I hit the AI or AI hit me, whoever got hit showed the Damage animation. But after the split I did, with the separate Managers for AI and Player, I have two options. Either I hit the AI, he does Damage animation and when he hits me I get and error. Or he hits me, I have the Damage animations and when I hit him I get an error. The error is this:
NullReferenceException: Object reference not set to an instance of an object
DamageScript.OnTriggerEnter2D (UnityEngine.Collider2D col) (at Assets/Scripts/DamageScript.cs:19)
This is the original DamageScript:
public class DamageScript : MonoBehaviour {
void OnTriggerEnter2D(Collider2D col)
{
if(col.transform.root != transform.root && col.tag != "Ground" && !col.isTrigger)
{
if (!col.transform.GetComponent<AIManager>().damage && !col.transform.GetComponent<PlayerManager>().blocking)
{
col.transform.GetComponent<AIManager>().damage = true;
col.transform.root.GetComponentInChildren<Animator>().SetTrigger("Damage");
}
}
}
}
This way my Player does the Damage animation, I get the error when I hit. So, I figured something like this would work, but I guess I don't really know how to code it:
void OnTriggerEnter2D(Collider2D col)
{
if(col.transform.root != transform.root && col.tag != "Ground" && !col.isTrigger)
{
line 11 if (!col.transform.GetComponent<AIManager>().damage && !col.transform.GetComponent<AIManager>().blocking)
{
col.transform.GetComponent<AIManager>().damage = true;
col.transform.root.GetComponentInChildren<Animator>().SetTrigger("Damage");
}
else
{
if (!col.transform.GetComponent<PlayerManager>().damage)
{
line 19 col.transform.GetComponent<PlayerManager>().damage = true;
col.transform.root.GetComponentInChildren<Animator>().SetTrigger("Damage");
}
}
}
}
}
Not surprisingly, it doesn't work and I still get crashes on some hits.
Any help would be appreciated, if possible.
Thank you!
From the situation you've described, I'll assume the error is being, primarily, by faulty refactoring of responsibility delegation.
More specifically, I believe it's sufficiently clear that the tutorial you've followed didn't follow single responsibility principle properly, and instead, implemented multiple responsibilities (player and AI) on a single class/file, to save time for the video, or to simplify the tutorial.
Later, when splitting the responsibilities to two scripts and two objects, you, as a beginner, was/is unaware of some details and/or pitfalls involved in reference management, and so are failing to assign references to both objects, or failing to handle missing references as the scripts are now split.
The problem arises because, if your player and AI now have different sets of scripts; one with each manager, but neither with both (unlike before, when both player and AI objects had "both"); then, either on the first or second if*manager.damage statement, the manager in question would not be found with GetComponent because it's not in that object, and upon trying to access fields/properties/methods on a null reference, the NullReferenceException would be thrown.
The solution is simply to do the proper null checks before accessing such fields/properties/methods, to guard from the exception and proceed to the second if statement if the first's manager is found to be null.
While at it, might as well cache the queries to make things better, as RetiredNinja recommended in the comments.
Code:
void OnTriggerEnter2D(Collider2D col) {
if(col.transform.root != transform.root && col.tag != "Ground" && !col.isTrigger) {
//Cache to avoid multiple queries and to simplify access
var playermanager = col.transform.GetComponent<PlayerManager>(); //One of these won't be found and will receive null instead
var aiManager = col.transform.GetComponent<AIManager>(); //One of these won't be found and will receive null instead
var animator = col.transform.root.GetComponentInChildren<Animator>();
if (aiManager != null //Null-check was missing
&& !aiManager.damage && !aiManager.blocking) { //Much nicer
aiManager.damage = true;
if(animator!=null)
animator.SetTrigger("Damage");
}
else {
if (playerManager != null && !playerManager.damage) {
playerManager.damage = true;
animator.SetTrigger("Damage");
}
}
}
}

Processing - If statement and ids

I'm an Italian student and I'm new in programming. I need your help for a school project.
I'm making a blob tracking program using Daniel Shiffman's tutorials. Currently I have 2 blobs on the screen. I am identifying them with 2 IDs: number 0 and number 1.
I need to put some conditions on those blobs: if one blob is in a certain part of the screen and the other one is in another part, I need to call a function.
I don't know how to put the if conditions separately for the two ids. Below is some pseudo code of what I would like to achieve:
for (id==0)
if (...) and
for (id==1)
if(...) then {
void()
}
I would really appreciate any help!
I don't really know where you want the blobs to be when the desired function fires, but I can try to give you an example...
Blob
Assign some sort of position variable, in this case PVector, to your blob object.
class Blob {
PVector position;
Blob (PVector position) {
this.position = position;
}
void update() {
*random movements, etc...*
}
}
Create two blob objects
Create two objects and assign a position to each of them.
Blob[] blobs = new Blob[2];
void setup() {
size(400, 400);
blobs[0] = new Blob(5, new PVector(40, 40));
blobs[1] = new Blob(13, new PVector(100, 100));
}
Check if blobs is at left or right side of the screen
I check if blob[0] is at the left side of the screen and if blob[1] is at right side of the screen. If they are, at the same time, the desiredFunction(); will fire.
void draw() {
for (int i = 0; i < blobs.length; i++) {
blobs.update();
}
if (blobs[0].position.x < (width / 2) && blobs[1].position.x < (width / 2) {
desiredFunction();
}
}
Remember
This is just an example. You could of course check other parts of the screen instead of the left and right parts. You can also use IDs on your blobs instead of an array, I just thought it was better to just use an array in this case.
PS: I wrote this answer without having processing started. The code has certainly a couple of typing errors.
For the example you have described, you can achieve this using the && operator in one if statement.
First assign the conditions you want to test to boolean variables. For example, create the boolean variables id0IsThere, and id1IsThere, and set them to true if the blobs are in the locations you want them to be in. Then use the following if statement:
if (id0IsThere && id1IsThere) {
yourFunction();
}
The && operator means that the code inside the if statement that executes yourFunction() is only executed if both conditions are true. In this case, if both blobs are in the positions you want them to be in. Hope that helps. Read more about if statements and the && operator here:
https://processing.org/reference/if.html
https://processing.org/reference/logicalAND.html

Simple 2-step animation using Unity's Animation Tool

I am new to Unity/coding and trying to create a simple 2-step animation in which I can adjust the delay times for each step. I have a lift in my game that uses two animations: "Up" and "Down".
I'm using an enumerator to play the animations, and this is what I have so far:
IEnumerator Go()
{
while(true)
{
GetComponent<Animation>().Play ("Up");
yield return new WaitForSeconds(delayTime);
break;
GetComponent<Animation>().Play ("Down");
yield return new WaitForSeconds(delayTime);
break;
}
}
I understand I could just animate the whole thing as one motion, but I want to be able to adjust the delay times on the fly. My goal is to animate these two in succession. Up, then down. At the moment my lift goes up and stays there. What am I doing wrong?
Thanks for the help!
Remove the break-clauses:
IEnumerator Go()
{
while(true)
{
GetComponent<Animation>().Play ("Up");
yield return new WaitForSeconds(delayTime);
GetComponent<Animation>().Play ("Down");
yield return new WaitForSeconds(delayTime);
}
}
Now it should loop the two animations. In the original code the break statements are causing the execution jump out of the loop and, therefore, the Play for the "Down" is never called and execution of the function is terminated.
If you want the lift go up and down only once you need to remove the while loop.

Flixel Game Over Screen

I am new to game development but familiar with programming languages. I have started using Flixel and have a working Breakout game with score and lives.
I am just stuck on how I can create a new screen/game over screen if a player runs out of lives. I would like the process to be like following:
Check IF lives are equal to 0
Pause the game and display a new screen (probably transparent) that says 'Game Over'
When a user clicks or hits ENTER restart the level
Here is the function I currently have to update the lives:
private function loseLive(_ball:FlxObject, _bottomWall:FlxObject):void
{
// check for game over
if (lives_count == 0)
{
}
else
{
FlxG:lives_count -= 1;
lives.text = 'Lives: ' + lives_count.toString()
}
}
Here is my main game.as:
package
{
import org.flixel.*;
public class Game extends FlxGame
{
private const resolution:FlxPoint = new FlxPoint(640, 480);
private const zoom:uint = 2;
private const fps:uint = 60;
public function Game()
{
super(resolution.x / zoom, resolution.y / zoom, PlayState, zoom);
FlxG.flashFramerate = fps;
}
}
}
There are multiple ways to go about doing this...
You could use different FlxStates, like I described in the answer to your other post: Creating user UI using Flixel, although you'll have to get smart with passing the score or whatever around, or use a Registry-type setup
If you want it to actually work like you described above, with a transparent-overlay screen, you can try something like this (keep in mind, the exact details may differ for your project, I'm just trying to give you an idea):
First, make sure you have good logic for starting a level, lets say it's a function called StartLevel.
You'll want to define a flag - just a Boolean - that tracks whether or not the game is still going on or not: private var _isGameOver:Boolean; At the very end of StartLevel(), set this to false.
In your create() function for your PlayState, build a new FlxGroup which has all the things you want on your Game Over screen - some text, an image, and something that says "Press ENTER to Restart" (or whatever). Then set it to visible = false. The code for that might look something like:
grpGameOver = new FlxGroup();
grpGameOver.add(new FlxSprite(10,10).makeGraphic(FlxG.Width-20,FlxG.Height-20,0x66000000)); // just a semi-transparent black box to cover your game screen.
grpGameOver.add(new FlxText(...)); // whatever you want to add to the group...
grpGameOver.visible = false;
add(grpGameOver); // add the group to your State.
Depending on how your game is setup, you may also want to set the objects in your group's scrollFactor to 0 - if your game screen scrolls at all:
grpGameOver.setAll("scrollFactor", new FlxPoint(0,0));
In your update() function, you'll need to split it into 2 parts: one for when the game is over, and one for if the game is still going on:
if (_isGameOver)
{
if (FlxG.keys.justReleased("ENTER"))
{
grpGameOver.visible = false;
StartLevel();
}
}
else
{
... the rest of your game logic that you already have ...
}
super.update();
Keep in mind, if you have things that respond to user input anywhere else - like a player object or something, you might need to change their update() functions to check for that flag as well.
Then, the last thing you need to do is in your loseLive() logic:
if (lives_count == 0)
{
_isGameOver = true;
grpGameOver.visible = true;
}
else
...
That should do it!
I would highly recommend spending some time with different tutorials and sample projects to kind of get a better feel for Flixel in general. Photon Storm has some great material to play with (even though he's jumped over to HTML5 games)
I also want to note that if you get comfortable with the way Flixel handles updates, you can get really smart with your state's update() function and have it only call update on the grpGameOver objects, instead of having to change all your other objects updates individually. Pretty advanced stuff, but can be worth it to learn it.

Resources