I'm trying to make a "thing" that checks/unchecks a specific object's interactable checkbox from an array by using player pref integers. The problem I'm having is I can't seem to reference specific objects from an array, please help.
Here's some script:
//This part is from the Start function.
for (int i = 0; i < buttons.Length; i++) {
if (PlayerPrefs.GetInt("button" + i) == null) {
PlayerPrefs.SetInt("button" + i, 1);
}
if (PlayerPrefs.GetInt("button" + i) == 1) {
button.interactable = true;
} else {
button.interactable = false;
}
}
void Update () {
for (int i = 0; i < buttons.Length; i++) {
if (PlayerPrefs.GetInt("button" + i) == 0) {
button.interactable = false;
}
}
}
The areas where you can see button.interactable = true/false are where I'm having problems.
If you don't have button defined somewhere else; I assume you are missing the concept of array index accessors; you might want to use buttons[i] instead of button.
Related
I'm new to programming and I got really stuck on an exercise.
I need to determine whether each character in the first string can be uniquely replaced by a character in the second string. Both strings are equal in length.
For example, "aabc ea" and "ddtf hd" , the result needs to be:
True
a => d
b => t
c => f
=>
e => h
If I have for example "abac ea" and "ddtf hd" , the result needs to be:
False
Since "abac ea" and "ddt hd" don't have an unique replacement.
This is my Code:
using System;
namespace UniqueStrings
{
class Program
{
static void Main(string[] args)
{
string firstPhrase = Console.ReadLine();
string secondPhrase = Console.ReadLine();
bool result = false;
int charsCount = 0;
char[] firstPhraseChars = new char[firstPhrase.Length];
char[] secondPhraseChars = new char[secondPhrase.Length];
if (firstPhrase.Length != secondPhrase.Length)
{
result = false;
}
for (int i = 0; i < firstPhrase.Length; i++)
{
if (firstPhrase[i] == firstPhraseChars[i])
{
firstPhraseChars[i] = firstPhrase[i];
secondPhraseChars[i] = secondPhrase[i];
}
for (int j = 0; j < secondPhrase.Length; j++)
{
if (secondPhrase[j] == secondPhraseChars[j])
{
firstPhraseChars[j] = firstPhrase[j];
secondPhraseChars[j] = secondPhrase[j];
result = false;
}
else
{
result = true;
}
}
}
for (int i = 0; i < firstPhrase.Length; i++)
{
if (result == false)
{
firstPhraseChars[charsCount] = firstPhrase[i];
secondPhraseChars[charsCount] = secondPhrase[i];
charsCount++;
}
}
if (result == false)
Console.WriteLine(result);
else
{
Console.WriteLine(result);
for (int i = 0; i < firstPhrase.Length; i++)
{
Console.WriteLine(firstPhrase[i] + " => " + secondPhrase[i]);
}
}
Console.Read();
}
}
}
Can someone please help me understand what I'm doing wrong? I have no idea anymore and I feel like this code will never work. There needs to be some solution to this, which I'm not understanding.
I'm not supposed to use LINQ, list or dictionary, only System.
If anyone has other questions, feel free to ask.
exemple of non-optimized solution
using System;
namespace UniqueStrings
{
class Program
{
static bool CheckStringSimilarity(string firstPhrase, string secondPhrase)
{
if (firstPhrase.Length != secondPhrase.Length)
{
return false;
}
var length = firstPhrase.Length;
for (var i =0; i<length; i++)
{
for(var j=0; j<length; j++ )
{
if((firstPhrase[i] == firstPhrase[j]) && (secondPhrase[i] != secondPhrase[j]))
{
return false;
}
if((firstPhrase[i] != firstPhrase[j]) && (secondPhrase[i] == secondPhrase[j]))
{
return false;
}
}
}
return true;
}
static void Main(string[] args)
{
Console.WriteLine($"CheckStringSimilarity('aaa','bbb') = {CheckStringSimilarity("aaa", "bbb")}");
Console.WriteLine($"CheckStringSimilarity('aaab','bbbc') = {CheckStringSimilarity("aaab", "bbbc")}");
Console.WriteLine($"CheckStringSimilarity('rrt','aze') = {CheckStringSimilarity("rrt", "aze")}");
Console.WriteLine($"CheckStringSimilarity('rrt dd','aad aa') = {CheckStringSimilarity("rrt dd", "aad aa")}");
}
}
}
DEMO
In your first for loop the result will always be true since both if statements will always return false. When the if statements compare their values "firstPhraseChars[i]" and "secondPhraseChars[j]" are always empty since you never put anything into these arrays before the comparison.
Hope this helps without giving away too much ;)
You can look for a counter example: if you've found it, correspondent doesn't exist:
private static bool HasCorrespondence(string left, string right) {
if (left == null)
return right == null;
if (right == null)
return false;
if (left.Length != right.Length)
return false;
// known correspondence
Dictionary<char, char> correspondence = new Dictionary<char, char>();
for (int i = 0; i < left.Length; ++i)
if (correspondence.TryGetValue(left[i], out char expected)) {
// counter example: we want expected, but have right[i]
if (expected != right[i])
return false;
}
else
// we have nothing for left[i], so we can add (left[i], right[i]) pair
correspondence.Add(left[i], right[i]);
// no counter example exists, return true
return true;
}
If Dictionary is prohibited, you can emulate it with help of array:
private static bool HasCorrespondence(string left, string right) {
if (left == null)
return right == null;
if (right == null)
return false;
if (left.Length != right.Length)
return false;
int[] correspondence = new int[char.MaxValue];
for (int i = 0; i < left.Length; ++i)
if (correspondence[left[i]] != 0) {
if (correspondence[left[i]] != right[i])
return false;
}
else
correspondence[left[i]] = right[i];
return true;
}
If you are looking for one to one correspondence, you can just check twice"
private static bool HasOneToOne(string left, string right) =>
HasCorrespondence(left, right) &&
HasCorrespondence(right, left);
Basically I have done a code which works as a shift selection, I have already programmed the file selection working with Ctrl-Key selection, but it is required to optimize it. Nevertheless I have not found any way to make it easier has anyone any idea of how could I achieve that? The highlightedIndex is a list of int.
private int lastClickedPointIdx = -1;
int firstvaluepoint = 0;
private int movingPointIdx = -1; //-1: no point moving
private void KeySelection()
{
bool shiftclick = false;
int firstselectedpoint = 0;
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) //Ctrl
{
if (highlightedIndex.Contains(movingPointIdx)) //remove point if already is in the highlightedIndex list
{
highlightedIndex.Remove(movingPointIdx);
firstselectedpoint = movingPointIdx;
shiftclick = false;
return;
}
else //otherwise add it to the highlightedIndex list
{
highlightedIndex.Add(movingPointIdx);
highlightedIndex.Sort();
firstselectedpoint = movingPointIdx;
shiftclick = false;
}
}
else if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) //Shift
{
if (!shiftclick)
{
highlightedIndex.Clear();
shiftclick = true;
}
if (lastClickedPointIdx > -1) //highlights all points
{
if (firstvaluepoint > firstselectedpoint)
{
for (int i = firstselectedpoint; i <= firstvaluepoint; i++)
{
highlightedIndex.Add(i);
}
}
else
{
for (int i = firstvaluepoint; i <= firstselectedpoint; i++)
{
highlightedIndex.Add(i);
}
}
}
}
lastClickedPointIdx = movingPointIdx;
if (!shiftclick)
firstvaluepoint = firstselectedpoint;
}
char SideA = 'A';
char SideB = 'B';
int CPUPlayer = 1;
Test.Text = x.ToString();
if (difficulty == 1)
{
if (CPUPlayer == 1)
{
string targetString = "";
for (int side = 1; side <= 1; side++)
{
targetString = SideA.ToString();
Test.Text = targetString.ToString();
for (int game = 1; game < 25; game++)
{
targetString = game.ToString();
for (int tile = 1; tile < 10; tile++)
{
targetString = tile.ToString();
PictureBox target = (PictureBox)(this.Controls.Find(targetString, true))[0];
if (target.BackgroundImage == null)
{
target.BackgroundImage = Properties.Resources.smallo;
Test.Text = targetString.ToString();
}
}
}
}
}
}
So I'm trying to loop through prenamed PictureBoxes (Ex: A11,A12,A13....etc) to have them change background Images by using the loop through string to connect to the pictureboxes but I keep getting Index is out of range from the PictureBox target = (PictureBox)(this.Controls.Find(targetString, true))[0];
I'm not sure what to do to fix it. I'm very new to c# and coding in general so would be nice to know what I'm missing!
To help you find the problem change
PictureBox target = (PictureBox)(this.Controls.Find(targetString, true))[0];
to
var found = this.Controls.Find(targetString, true);
if(found == null || found.Length < 1 ) {
throw new Exception("Picture not found")
}
After that, set a breakpoint in the throw line and find out why the picture was not found.
So turns out it was just my .ToString(); logic that was just flat out wrong and the string was coming out as a picturebox that didn't exist. This is the code that works:
if (difficulty == 1)
{
if (CPUPlayer == 1)
{
string targetString = "";
for (int side = 1; side <= 1; side++)
{
for (int game = 1; game < 25; game++)
{
for (int tile = 1; tile < 10; tile++)
{
targetString = SideA;
targetString += game.ToString();
targetString += tile.ToString();
Test.Text = targetString.ToString();
PictureBox target = (PictureBox)(this.Controls.Find(targetString, true))[0];
I read saved data from tbl in a list, and i want to edit the object, so when i start the program, combobox first to show saved value for that object, and others also to be in the combobox. Please help !
if (lstP.Count > 0)
{
for (int i = 0; i < lstP.Count; i++)
{
if (Stav.IDP == lstP[i].SP)
{
Prim.SelectedIndex = lstP[i].SP;
//ERROR
break;
}
}
}
SelectedIndex requires a number to be passed. What you need is to assign an i to it:
if (lstP.Count > 0)
{
for (int i = 0; i < lstP.Count; i++)
{
if (Stav.IDP == lstP[i].SP)
{
Prim.SelectedIndex = i;
break;
}
}
}
Whats the best way to swap two ListView items in C#? I see that the standard ListView doesn't implement such functionality.
--
Best Regards,
Murat
Building upon the KnowDotNet article ref'd by Murat, here's my extension method that is a bit more flexible (it operates on any item, not just the cursel), and bugfixed (BeginUpdate/Endupdate for less flicker, EnsureVisible, and bounds checking).
Doesn't need to be an extension method, but I like them :)
namespace YourApp
{
public static class MyExtensions
{
// Based upon http://www.knowdotnet.com/articles/listviewmoveitem.html
public static void MoveSelectedItem(this System.Windows.Forms.ListView lv, int idx, bool moveUp)
{
// Gotta have >1 item in order to move
if(lv.Items.Count > 1)
{
int offset = 0;
if (idx >= 0)
{
if (moveUp)
{
// ignore moveup of row(0)
offset = -1;
}
else
{
// ignore movedown of last item
if (idx < (lv.Items.Count - 1))
offset = 1;
}
}
if (offset != 0)
{
lv.BeginUpdate();
int selitem = idx + offset;
for (int i = 0; i < lv.Items[idx].SubItems.Count; i++)
{
string cache = lv.Items[selitem].SubItems[i].Text;
lv.Items[selitem].SubItems[i].Text = lv.Items[idx].SubItems[i].Text;
lv.Items[idx].SubItems[i].Text = cache;
}
lv.Focus();
lv.Items[selitem].Selected = true;
lv.EnsureVisible(selitem);
lv.EndUpdate();
}
}
}
}
}
If you use custom ListViewItem, or object you cannot clone object, or stock in string:
enum Direction { UP = -1, DOWN = +1};
void ListViewMove(ListView lv, Direction direction)
{
if (lv.SelectedItems.Count > 0)
{
int selIdx = lv.SelectedItems[0].Index;
ListViewItem tmp = lv.Items[selIdx] ;
if ( ( (selIdx != 0) && direction == Direction.UP ) ||
((selIdx!=lv.Items.Count-1) && (direction == Direction.DOWN)) )
{
lv.Items.RemoveAt(selIdx);
tmp = lv.Items.Insert(selIdx + (int)direction, tmp);
tmp.Selected = true;
}
}
lv.Focus();
}
Both ASP.NET and Winforms ListView have Items property which allows to add or removed items.
I´ve wrote a little sample that should work.
ListViewItem[] copyOfItemsInListView1 = new ListViewItem[listView1.Items.Count];
ListViewItem[] copyOfItemsInListView2 = new ListViewItem[listView2.Items.Count];
listView1.Items.CopyTo(copyOfItemsInListView1, 0);
listView2.Items.CopyTo(copyOfItemsInListView2, 0);
listView1.Items.Clear();
listView2.Items.Clear();
for (int i = 0; i < copyOfItemsInListView2.Length; i++)
{
listView1.Items.Add(copyOfItemsInListView2[i]);
}
for (int i = 0; i < copyOfItemsInListView1.Length; i++)
{
listView2.Items.Add(copyOfItemsInListView1[i]);
}
Clone them:
// move selected item up
int selectedIndex = mListView.SelectedIndices[0];
if (selectedIndex > 0)
{
ListViewItem item1 = (ListViewItem)mListView.Items[selectedIndex - 1].Clone();
ListViewItem item2 = (ListViewItem)mListView.Items[selectedIndex].Clone();
mListView.Items[selectedIndex - 1] = item2;
mListView.Items[selectedIndex] = item1;
mListView.SelectedIndices.Remove(selectedIndex);
mListView.SelectedIndices.Add(selectedIndex - 1);
}