I have a tree control with checkboxes next to each node that allows for checked, unchecked and middle checked states on the nodes. When clicking a node, the parent and children are updated. The code I found that does the trick uses bit shifting and I'm trying to understand what exactly is happening.
Can someone explain the following code? Or even better, rewrite this code so it is easier to understand?
// click event handler
private function eventMessageTree_itemCheckHandler(event:TreeEvent):void {
var node:ITreeNode = ITreeNode(event.item);
var checkState:uint = TreecheckboxItemRenderer(event.itemRenderer).checkBox.checkState;
updateParents(node, checkState);
updateChilds(node, checkState);
}
private function updateChilds(item:ITreeNode, value:uint):void {
var middle:Boolean = (value & 2 << 1) == (2 << 1);
var selected:Boolean = (value & 1 << 1) == (1 << 1);
if (item.children.length > 0 && !middle) {
for each (var childNode:ITreeNode in item.children) {
childNode.checked = value == (1 << 1 | 2 << 1) ? "2" : value == (1 << 1) ? "1" : "0";
updateChilds(childNode, value);
}
}
}
private function updateParents(item:ITreeNode, value:uint): void {
var checkValue:String = (value == (1 << 1 | 2 << 1) ? "2" : value == (1 << 1) ? "1" : "0");
var parentNode:ITreeNode = item.parent;
if (parentNode) {
for each (var childNode:ITreeNode in parentNode.children) {
if (childNode.checked != checkValue) {
checkValue = "2";
}
}
parentNode.checked = checkValue;
updateParents(parentNode, value);
}
}
It looks like the checkState value in the control can be either 1, 2, or 4 (or possibly 0, 2, and 4?):
public static const CONTROL_UNCHECKED:uint = 1; // not checked, and some descendants are
public static const CONTROL_CHECKED:uint = 2; // checked, and all descendants are
public static const CONTROL_MIDDLE:uint = 4; // not checked, but some descendants are
while the checked value in the nodes can be either 0, 1, or 2:
public static const UNCHECKED:uint = 0; // not checked, and some descendants are
public static const CHECKED:uint = 1; // checked, and all descendants are
public static const MIDDLE:uint = 2; // not checked, but some descendants are
That's really confusing. Ideally these would be the same set of constants.
To update:
private function controlStateToNodeState(value:uint):uint {
return value / 2;
}
...
updateParents(node, controlStateToNodeState(checkState));
updateChilds(node, controlStateToNodeState(checkState));
...
/** Updates the descendants of the node based on state:
* If value is CHECKED, all children are CHECKED
* If value is UNCHECKED, all children are UNCHECKED
* If value is MIDDLE, children are left alone
*/
private function updateChilds(item:ITreeNode, value:uint):void {
if (value == MIDDLE) {
return; // if value is MIDDLE, children are left alone
}
// not middle, so update all children to my state
for each (var childNode:ITreeNode in item.children) {
childNode.checked = value;
updateChilds(childNode, value);
}
}
}
/**
* Updates the ancestor nodes based on state:
* If value is CHECKED, ancestors are made MIDDLE if not already checked
* If value is MIDDLE, ancestors are made middle (they should not already be CHECKED)
*/
private function updateParents(item:ITreeNode, value:uint): void {
...
}
Basically, an expression like this:
var middle:Boolean = (value & 2 << 1) == (2 << 1);
Is counter-intuitive. You usually test bits by shifting the constant 1 to the left, since that lets the number of bits shifted be the same as the index of the bit, counting the LSB (rightmost) bit as bit number 0.
Also, there's no point in testing the result with a == comparison, since it's always going to be either 0 or non-zero, so you can at least test for something simpler if your language requires that.
In C and C++, which by default interpret a non-zero integer as "true", the comparison is totally unnecessary and just serves to introduce clutter, repetition, and increase the risk of bugs.
I'd write this like so:
var middle:Boolean = (value & (1 << 2)) != 0;
The extra parenthesis should help make it clearer how things are grouped. Note how "2 << 1" was rewritten as "1 << 2". This is not just a "switch", you need to compute the proper shift to get the same bit value, 4 in this case.
Of course you could put the bit-testing into subroutines and call them, to make the code more readable.
Related
I'm developing a program that people can play "tic tac toe" with a computer.
I choose structured text as my develop language, but it doesn't have recursion, so I have to develop it without recursion.
As the result, I decide to use the stack to instead, but I don't know how to change recursion into the stack.
I try to use stack like BFS, and also I wanna that minimax can make the best move.
I don't know Structured Text, but maybe it helps to see a solution in another language.
You need a stack with moves, so that when backtracking, you know from where to start to search for a next, alternative move for it.
You also need a stack of scores, so you know the best score so far at every depth of the minimax search tree.
The two stacks could be combined into one stack when you can store the two data in one structure to be placed on the single stack. But in the below implementation in JavaScript I have tried to keep the data structures as simple as possible and used two stacks (fix-sized arrays with a separate size variable). All variables are declared at the top of the functions (as in Structured Text), and return statements are always at the end of the function bodies (since there is no return statement in Structured Text).
function gameWon(board) {
/* Looks at all possible lines of 3,
* to see if they are occupied by three of the same symbols
* board: is a 1D array with 9 integers:
* 1 = "X" (first player), 0 = free, 1 = "O"
* Returns boolean.
*/
let value;
let i;
// In Structured Text you'd not have gameWonReturn,
// as you would use `gameWon` instead for returning a value
let gameWonReturn = false;
for (i = 0; i < 3; i++) {
value = board[i*3];
if (value != 0 && value == board[i*3+1] && value == board[i*3+2]) {
gameWonReturn = true;
break;
}
value = board[i];
if (value != 0 && value == board[i+3] && value == board[i+6]) {
gameWonReturn = true;
break;
}
if (value != 0 && value == board[4] && value == board[8-i]) {
gameWonReturn = true;
break;
}
}
return gameWonReturn;
}
function play(board, moveStack, moveCount, move) {
let playReturn;
// Derive played symbol from number of moves played
board[move] = 1 - (moveCount % 2) * 2; // Use MOD operator. Result is 1 or -1
moveStack[moveCount] = move; // Log move in stack
playReturn = moveCount + 1;
return playReturn;
}
function minimax(board, moveStack, moveCount) {
const scoreStack = Array(10); // Array of signed integers
const originalMoveCount = moveCount;
let move; // -1..9
let score; // -10..10
let player; // -1 or 1
let minimaxReturn = -1; // -1..9
while (true) {
// Current player can be derived from the number of moves that were played
player = 1 - (moveCount % 2) * 2; // 1 = First, maximizing player. -1 = Second, minimizing player
// Check for game-over
if (gameWon(board)) { // Preceding move resulted in win for previous player
scoreStack[moveCount] = -(10 - moveCount) * player; // Earlier wins get greater score
} else if (moveCount == 9) { // It's a draw
scoreStack[moveCount] = 0;
} else {
moveStack[moveCount] = -1; // Prepare for iterating moves for current player
scoreStack[moveCount] = -player * 10; // Initialize with worst possible score for current player
moveCount++;
}
do { // Repeat:
moveCount--;
if (moveCount < originalMoveCount) { // All done
break; // Exit point
}
// Look for a next, valid move
move = moveStack[moveCount];
if (move >= 0) { // Was a valid move: derive score from deeper results
score = scoreStack[moveCount + 1]; // Best score opponent can get
if ((board[move] == 1) == (score > scoreStack[moveCount])) { // Improvement
scoreStack[moveCount] = score;
if (moveCount == originalMoveCount) {
minimaxReturn = move; // For now this is a best move...
}
}
// Take back move
board[move] = 0;
}
// Look for next valid move
do {
move++;
} while (move < 9 && board[move] != 0) // Occupied
} while (move == 9); // Backtrack (i.e. repeat loop) when all moves were tried
if (moveCount < originalMoveCount) { // All done
break; // Exit point
}
// Play move
moveCount = play(board, moveStack, moveCount, move);
}
return minimaxReturn;
}
function main() {
const board = Array(9).fill(0); // An empty 3x3 board as 1 dimensional array
const moveStack = Array(10); // History of played moves (indices in board)
let moveCount = 0; // Number of moves played
let bestMove;
/* Demo:
* Play moves to arrive at this board:
*
* X | O |
* ---+---+---
* O | |
* ---+---+---
* X | |
*/
moveCount = play(board, moveStack, moveCount, 0); // Play X in top-left
moveCount = play(board, moveStack, moveCount, 1); // Play O next to it
moveCount = play(board, moveStack, moveCount, 6); // Play X in bottom-left
moveCount = play(board, moveStack, moveCount, 3); // Play O in middle row
// Run minimax for suggesting where to play an "X":
bestMove = minimax(board, moveStack, moveCount);
console.log(bestMove); // 4 (center of the board)
}
main();
I'm in the process of creating a QT application which is using multiple (14) qcheckboxes. I need to have a limit (preferably set as a variable that i can change) to the number of checkboxes that can be checked at the same time, is there any way to achieve this cleanly ? Thanks for your time.
There is no simple way of doing this, you have to write your code to do it.
I suppose you have the checkboxes in some parent widget class. So I would create a slot which looks like this.
void SomeParentWidget::onCheckBoxToggled(bool value)
{
// when we unchecked the checkbox,
// we do not need to count the number of checked ones
if (!value)
return;
int total = 0;
int limit = 15; // your "magic" number of maximum checked checkboxes
for (auto chb : allCheckBoxes()) // allCheckBoxes() is some method which returns all the checkboxes in consideration
{
if (chb->isChecked())
{
++total;
if (total > limit)
{
// too many checkboxes checked! uncheck the sender checkbox
// Note: you may want to add some nullptr checks or asserts to the following line for better robustness of your code.
qobject_cast<QCheckBox*>(sender())->setChecked(false);
return;
}
}
}
}
And when creating each of your checkboxes inside some parent widget, connect this slot to their signal:
auto chb = new QCheckBox();
connect(chb, &QCheckBox::toggled, this, &SomeParentWidget::onCheckBoxToggled);
Implementation of allCheckBoxes() is up to you, I do not know how you can retrieve the collection of all your check boxes. Depends on your design.
I found another, even simpler solution. Use this slot.
void SomeParentWidget::onCheckBoxToggled(bool value)
{
static int totalChecked = 0; // static! the value is remembered for next invocation
totalChecked += value ? 1 : -1;
Q_ASSERT(totalChecked >= 0);
int maxChecked = 15; // any number you like
if (value && totalChecked > maxChecked)
{
qobject_cast<QCheckBox*>(sender())->setChecked(false);
}
}
... and connect it to checkboxes' toggled() signal. Note that in order to work correctly, all check boxes must be unchecked at the time when you make the signal-slot connection because this function starts counting from zero (0 is the initial value of the static variable).
You can store all your checkboxes in a map (either in an std::map, an std::unordered_map or an QMap). Your keys will be your checkboxes, and your values will be their states, so something like this:
std::unordered_map<QCheckBox*, bool> m_checkBoxStates;
Here's what your connected to your toggled signal of all your checkboxes look like (keep in mind that all the signals will be connected to the same slot):
void MainWindow::onToggled(bool checked) {
QCheckBox* checkBox = sender(); //the checkbox that has been toggled
m_checkBoxStates[checkBox] = checked;
if (!checked) {
return;
}
const int count = std::count_if(m_checkBoxStates.begin(), m_checkBoxStates.end(),
[](const auto pair) {
return pair.second == true;
});
if (count > maxCount) {
checkBox->setChecked(false);
}
}
Hi. I am having trouble writing this method (in the photo) in a recursuve format. The method gets the amount of occurences of a given element in the binary search tree.
To solve this recursively, I was trying to implement it with a private helper method of the same name, like this:
public int count(){
count = 0;
if (root == null)
return count;
return count (root.getInfo());
private int count(T element){
(Basically the same code you see in the photo)
}
but I ended up with overflow errors. Would you mind taking a look and telling me how I can structure this method recursively?
Cheers, and thanks.
A tentative implementation may looks like this.
public int count(T element, T root){
if(element == null) {
return 0;
}
int count = 0;
int compare = element.compareTo(root.getInfo());
if(compare == 0){
count++;
}
count += count(element, root.getLeft());
count += count(element, root.getRight());
return count;
}
count(item, root);
Im working on the collision detection in my 2D Processing 2.2.1 game. Basically what I did was write a class which creates a box by defining the coordinates of its endpoints and which has a method to check if two of these boxes overlap. I did this by introducing a boolean which is set to true as soon two of these boxes overlap. Then basically implementing a get method which creates these boxes, I run into a return a result of type error. It says that the method is not returning the correct type of Box1. I dont really understand since the box which I am returning does fit the constructor. I am pretty sure it is due to the fact that the objects colliding are in an array which generates more and more objects with time, but I sadly do not know how I would have to change my Collider ( Box1) class.
here is the code im getting the error on:
//returning collider info
public Box1 getBox1() {
for (int i =frameCount/600; i >0; i--) {
return new Box1( block[i].x - Blockpic.width/2, block[i].y-Blockpic.height/2, block[i].x+Blockpic.height/2, block[i].y+Blockpic.height/2);
}
}
this is my collider (Box1) class:
public class Box1 {
float x1, x2;
float y1, y2;
Box1( float x1, float y1, float x2, float y2 ) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
boolean isOverlap( Box1 b ) {
if ((( x1 <= b.x1 && b.x1 <= x2 ) || ( x1 <= b.x2 && b.x2 <= x2 ))
&& (( y1 <= b.y1 && b.y1 <= y2 ) || ( y1 <= b.y2 && b.y2 <= y2 ))) {
return true;
}
return false;
}
}
just for complete info my spawning objects class ( where the error is situated) :
public class Blockfield {
private int Blockcount;
private PImage Blockpic;
private Block block[];
//Constructor
public Blockfield (int Blockcount) {
this.Blockcount = Blockcount;
Blockpic = loadImage("block2.png");
//new array
block = new Block [Blockcount];
for ( int i=0; i < Blockcount; i++) {
block[i] = new Block( width+Blockpic.width, random (height),7);
}
}
//Draw method for this class
public void draw () {
for (int i =frameCount/600; i >0; i--) {
pushMatrix();
translate ( block[i].x,block[i].y );
image ( Blockpic, block[i].x, block[i].y);
popMatrix();
}
}
public void update() {
for (int i =frameCount/600; i >0; i--) {
//moves blocks right to left
block[i].x -=(6 * (frameCount/200));
//spawns block when they leave the screen
if (block[i].x < 0 - Blockpic.width) {
block[i] = new Block( width+Blockpic.width, random (height),7);
}
}
}
//returning collider info
public Box1 getBox1() {
for (int i =frameCount/600; i >0; i--) {
return new Box1( block[i].x - Blockpic.width/2, block[i].y-Blockpic.height/2, block[i].x+Blockpic.height/2, block[i].y+Blockpic.height/2);
}
}
}
class Block {
float x, y;
int speed;
Block ( float x, float y, int speed) {
this.x= x;
this.y= y;
this.speed = speed;
}
}
Thanks alot!!!
The problem, as you say, is with this method:
public Box1 getBox1() {
for (int i =frameCount/600; i >0; i--) {
return new Box1( block[i].x - Blockpic.width/2, block[i].y-Blockpic.height/2, block[i].x+Blockpic.height/2, block[i].y+Blockpic.height/2);
}
}
Ignoring for a second that it doesn't make sense to have a return statement inside a for loop like this, the whole problem is that computers are too stupid to know what the value of frameCount is before they run the code. What if frameCount is 0? Or negative?
If frameCount is 0 or negative, then the body of the for loop will never be executed, and this method will never return anything. That's the error.
You might know that frameCount will always be positive, but the computer doesn't.
Edit: Continuing in response to your below comment:
If you want help, you have to provide an MCVE. Note that this should be as few lines as possible, just to get the basics across. We don't need any collision detection, just a function you call. Here's an example:
void setup(){
String s = getString(true);
println(s);
}
String getString(boolean b){
if(b){
return "testing";
}
}
If you try to run this code, you'll get an error telling you that "This method must return a result of type String".
The reason you get this error is because: what will the getString() function return if I pass in a value of false? It won't return anything! This is exactly like what your code is complaining about. We can see that getString() is only ever called with a value of true, but the computer isn't smart enough to figure that out.
You seem to misunderstand the power that a compiler has. It can't see what will happen at runtime. Even if it's obvious to you that the boolean will always be true (or in your case, that frameCount is always positive), the compiler can't know that. And since it can't know that, it's telling you that you might not return a value from a method with a return type, and that's a compiler error.
You need to refactor your code so that it always returns something from methods that have a return type. However, I'm skeptical that the for loop does what you think it does- but you haven't really explained what you think it does, so that's just a guess.
And the reason you didn't encounter this error in your other methods is because none of them contain this logical error. The only other function that has a return type is this one:
boolean isOverlap( Box1 b ) {
if (lotsOfLogic) {
return true;
}
return false;
}
Notice how even if the if statement evaluates to false, you still return something from this function. That's what you need to do with your getBox1() function.
I have just been studying the concept of recursion and I thought that I would try a simple example. In the following code, I am attempting to take the numbers: 1, 2, 3, 4, 5, and add them together using recursion. I expected the result to be 15, but my code is returning 16.
What am I doing wrong?
Code:
static void Main(string[] args)
{
Console.WriteLine(Sum(5));
Console.Read();
}
static int Sum(int value)
{
if (value > 0)
{
return value + Sum(value - 1);
}
else
{
return 1;
}
}
You're returning 1 in the else clause. You should be returning 0:
else
{
return 0;
}
If the value is not greater than zero, why would you return one in the first place?
Your code executes as follows:
Sum --> 5
Sum --> 4
Sum --> 3
Sum --> 2
Sum --> 1
Sum --> 0
1 <---
2 <---
4 <---
7 <---
11 <---
16 <---
Check your base case.
Others already noted the error, and I will elaborate on recursion.
Although C# does not currently perform tail call optimization (although IL has special tail instruction), it's worth mentioning that tail recursion is generally a good thing.
Tail recursion is a special case of recursion in which the last operation of the function, the tail call, is a recursive call. Since the last call is the recursive call there is no need to preserve stack frame of the calling function and the compiler can easily use this information to generate machine instruction such that the stack doesn't grow at all. So it can basically turn recursive function into an iterative one.
Rewriting your code to support tail recursion can be done as follws:
static int Sum(int result, int value)
{
if(value == 0)
return result;
return Sum(result + 1, value - 1);
}
static int Sum(int value)
{
if (value > 0)
{
return value + Sum(value - 1);
}
else
{
return 0; //Change this.
}
}
That's because, when the value is = 0, you return 1. Then it get's added.
Sum's "else" clause should return 0.
I always prefer to put the terminating case(s) up front so they're obvious, and I have a violent near-psychopathic hatred of "if cond then return a else return b" constructs. My choice would be (making it clear that it won't work properly for negative numbers):
static unsigned int Sum(unsigned int value) {
if (value == 0)
return 0;
return value + Sum(value - 1);
}
I believe that's far more readable than a morass of braces and control flow.
The others have already answered that question, but when I work with recursion, one of the things I like to do to check that it works is to use check the base case and one additional case. I your case I would test it with 1, which would yield 2. Since this is obviously wrong you might want to check for 0 which is not going to use any recursion and so it should be obvious that the error lies in the base class.
In general recursion is easier to reason about, since you can list the limited number of things you need to check, but it does initially require a leap of faith since your intuition will be wrong. Just test the edge cases and trust the math it will never fail.
int summation(int num){
if (num==1)
return 1;
return summation(num-1)+num;
}
I'm pretty sure the problem is because you want your recursion to terminate when value == 1, and it's currently terminating when value == 0.
Your terminating expression is at issue. When value == 0 (or lower), it should return a 0 rather than 1. For sake of efficiency (which, let's admit it here, obviously isn't a concern, otherwise recursion wouldn't have been used for this task), you should terminate the recursion at value == 1 and return a literal 1 to save one unnecessary level of recursion.
using System;
using NUnit.Framework;
namespace Recursion
{
[TestFixture()]
public class Test
{
[Test()]
public void TestSum ()
{
Assert.AreEqual (Sum (new int[] { }), 0);
Assert.AreEqual (Sum (new int[] { 0 }), 0);
Assert.AreEqual (Sum (new int[] { 1 }), 1);
Assert.AreEqual (Sum (new int[] { 1, 2, 3, 4, 5 }), 15);
}
public int Sum(int[] head)
{
if (head.Length == 0) return 0;
int[] tail = new int[head.Length - 1];
for (int i = 1; i < head.Length; i++)
{
tail [i-1] = head [i];
}
return head[0] + Sum (tail);
}
}
}
It could also be written like this:
public static int sum(int n){
int total;
if(n==1){
total =1;
}else{
total = sum(n-1)+n;
}
return total;
}
Actually, I think you don't need to check case else because
public static int sum(int number){
if(number > 0){
return number + sum(--number);
}
return number; // return 0 so that's why you don't need check else condition
}
To begin at the end, a recursive Sum method looks like this:
// version 3
public static int Sum(int startRange, int endRange)
{
if (endRange > startRange)
{
return endRange + Sum(startRange, endRange - 1);
}
if (endRange < startRange)
{
return startRange + Sum(endRange, startRange - 1);
}
return endRange;
}
Hardcoding the startRange to be 0 gives us:
// version 2
public static int Sum(int range)
{
if (range > 0)
{
return range + Sum(0, range - 1);
}
if (range < 0)
{
return Sum(range, -1);
}
return range;
}
...and if you want to limit the method to positive numbers only, there's no need for a sign:
// version 1
public static unsigned int Sum(unsigned int range)
{
if (range > 0)
{
return range + Sum(0, range - 1);
}
return range;
}
I hope this helps give more of an insight into summing number ranges via recursion.
static int Sum(int[] addends)
{
if (addends.Length == 1)
{
return addends[0];
}
else
{
int tailIndex = addends.Length - 1;
var subArray = addends[0..tailIndex];
return addends[tailIndex] + Sum(subArray);
}
}
Try this code:
def sumr(n):
if n==0:
return n
return n+sumr(n-1)