Update
Link to the C# Solution Project from a user who answered me:
https://github.com/TedDawkin/C64_AI_Movement
Update
I found it - if someone is interested just use the link to the thread in C64 Forum: http://www.lemon64.com/forum/viewtopic.php?p=712902#712902 where I discussed the topic (with myself). Funny how simple it was in the end. Not so funny that it took me over 2 weeks.
I will post the BASIC to C# code later and "answer" my own Question.
If someone cares and dont want to go to the forum link, here is how it works in C64 basic.
30110 IF KS(S)=0 THEN GOSUB 30400 : GOTO30105
30400 POKE 211,20: POKE214,18: SYS CS: PRINT"SPIELER"F
30405 Y=INT(KP(S,F)/40)
SYS CR, KP(S,F)-40*Y, Y
X=PEEK(UA)-1
Y=PEEK(UA+1)-40
30410 IF PEEK(UA+2)=1 OR PEEK (UA+3)=1 GOTO 30420
30415 IFINT(RND(1)*2)=0ORGW(KS(S),F)<4GOTO30450
30420 IFX=0THENX=Y:GOTO30215
30421 IFY<>0GOTO30450
30425 GOTO30215
30450 IFX<>0ANDRI(F)<>(1+2*(X=1))THENP=X:GOSUB30490:IFP=0THENRETURN
30451 IFY<>0ANDRI(F)<>(40+80*(Y=1))THENP=Y:GOSUB30490:IFP=0THENRETURN
30455 IFX<>0ANDRI(F)<>(1+2*(X=1))GOTO30460
30456 IFRI(F)<>-1THENP=1:GOSUB30490:IFP=0THENRETURN
30457 IFRI(F)<>1THENP=-1:GOSUB30490:IFP=0THENRETURN
30458 GOTO30465
30460 IFY<>0ANDRI(F)<>(40+80*(Y=1))GOTO30465
30461 IFRI(F)<>-40THENP=40:GOSUB30490:IFP=0THENRETURN
30462 IFRI(F)<>40THENP=-40:GOSUB30490:IFP=0THENRETURN
30465 RETURN
30490 Q=KP(S,F)+P:IFQ<0ORQ>520OR(PEEK(BR+Q)<>32ANDPEEK(BR+Q
<>96)THENRETURN
30491 POKEBR+KP(S,F),32:KP(S,F)=Q:POKEBR+KP(S,F),193:POKEFR+KP(S,F),6
30492 RI(F)=P:P=0:RETURN
some hints:
X = moved right (1), left (-1), up (-40) or down(40)
P = Position. There is no Y because the next/prev line is
40 characters away. (C64 Screen = 40 Columns and 25 Rows)
S = switches between 0 and 2 to determine if its human or ai turn
KP(S,F) = Offset-Position in Video-Memory-Adress
BR = Start-Adress of Video-Memory
32 = 0x20 = Space to clear old position
193 = Ascii-Character used as pawn for player and ai
6 = Mark field as AI (Human position is marked with 0x0b)
F = Playernumber
RI(F) = dont know yet
Original Question:
Working on a remake and trying to understand C64-Code I am struggling with the AI Movement. Working over a week on it, I cant reproduce the 100% same behavior.
To answer my question: Yes, an Ai can act randomly by using RND and I totally overlooked that.
For the in-depth discussion go to the Forum-Thread
There where other stumbling blocks that will maybe help if you want to debug/reverse engineer some stuff.
I always read the BASIC-Code without syntax highlighting and formatting. By doing this I missed some things and made errors.
Positions where marked in screen memory
Positions where not Point(x,y) or array[x,y] but an integer 0-999 representing the 25 rows and 40 columns of the C64-Screen
With the assembler part, I was to much in detail. It would have been better to look at 5 to 10 commands in a row and think about what could happend (without debugging) instead of getting lost in JSRs while debugging
Related
I am programming a boss fight using tModLoader for Terraria, and I am having issues.
1. The section commented as "// Run one of 4 normal attacks" is not running at all. (Okay, well, it might be, but at least the Main.NewText() sections aren't working.)
2. The random.Next() is returning 0.
I don't know if this question has been asked before (it wasn't in the list of suggestions you get when you begin to ask a question), so anything you can do is good. (My main issue is #1)
For #1 I have tried switching around the positions of the forloops and the if statements. This is all I can think of to do, unfortunately.
For #2 I cannot see what is wrong, and I haven't tried anything.
Code here: https://pastebin.com/yxe7XP8G (This bit here is what I think is the most likely explanation for this)
public override bool PreAI()
{
if (npc.ai[0] == 0)
{
Main.NewText("The power of sock fetishes overwhelms you...", 224, 147, 4, true);
npc.ai[0] = 1;
}
int hazumekAttackConj = 0;
int hazumekAttackIDCurrent = 0;
npc.TargetClosest(true);
Player player = Main.player[npc.target];
Random random = new Random();
// Run one of 4 normal attacks
Main.NewText(hazumekAttackIDCurrent);
I don't know what exactly is breaking here, so I will share my entire PreAI() hook.
No error messages are displaying.
I expect the chat output to be:
"Hazumek NRM Attack 1-4", then "Hazumek CNJ Attack S1"
Then, "Hazumek NRM Attack 1-4", then "Hazumek CNJ Attack S2". This should repeat forever.
The chat output is actually "Hazumek CNJ Attack S1" and then "Hazumek CNJ Attack S2" over and over again.
Last night I took CheatEngine for a ride, and I found a structure in the game i currently play. The game has 4 characters, each with "health" and "mana", both of these are 4 bytes (int). Is there a way I can scan the application to find the first occurrence?
What I found was that health of player 1 was located at 2DC2E72C, and I'm going to short it to "72C" since the other players health comes very exact after that.
Player 1 health: 72C
Player 2 health: 81C
Player 3 health: 90C
Player 4 health: 9FC
After some handywork with my trusted microsoft calculator, I found that it is 240 bytes between each players health. Players mana is 4 bytes, placed right after health, so the structure is:
000 Player 1 health
004 Player 1 mana
240 Player 2 health
244 Player 2 mana
and so on.
So my question is, could I search for this pattern in the applications memory? The pattern would be something along the line of: 2x4 bytes, 240 bytes, 2x4 bytes, 240 bytes....
If you have a text file containing the memory contents you could use regular expressions to search for the pattern you want. Boost has a good library for regular expressions.
I think there won't be a managed way to do that.
However, CheatEngine is an open source program, that does the same
http://www.cheatengine.org/
Maybe you could check out the source code and figure out which API calls you need to achive the same with C#
Update: I see, you already mentioned CheatEngine, overlooked it the first time.
I found this article on CodeProject http://www.codeproject.com/Articles/15680/How-to-write-a-Memory-Scanner-using-C
Looks simple
There was a cheat program back in the day called FreeCheese if I remember correctly. The way it worked was something like this :
Take search value from user input
Scan game's process memory for any values that match users input and
store found addresses
Ask user to change the value ingame and take
new value as input
Rescan addresses from step 2 and discard those that don't match the new value
Repeat steps 3 and 4 until an address (number of addresses) is found that always reflect the changes specified by the user
Ask the user for a new value and write that value to the addresses found
Step 6 is tricky since you will need to do type / size checks to make sure you can actually apply the new value.
Happy cheating :)
I have a few questions concerning backpropogation. I'm trying to learn the fundamentals behind neural network theory and wanted to start small, building a simple XOR classifier. I've read a lot of articles and skimmed multiple textbooks - but I can't seem to teach this thing the pattern for XOR.
Firstly, I am unclear about the learning model for backpropogation. Here is some pseudo-code to represent how I am trying to train the network. [Lets assume my network is setup properly (ie: multiple inputs connect to a hidden layer connect to an output layer and all wired up properly)].
SET guess = getNetworkOutput() // Note this is using a sigmoid activation function.
SET error = desiredOutput - guess
SET delta = learningConstant * error * sigmoidDerivative(guess)
For Each Node in inputNodes
For Each Weight in inputNodes[n]
inputNodes[n].weight[j] += delta;
// At this point, I am assuming the first layer has been trained.
// Then I recurse a similar function over the hidden layer and output layer.
// The prime difference being that it further divi's up the adjustment delta.
I realize this is probably not enough to go off of, and I will gladly expound on any part of my implementation. Using the above algorithm, my neural network does get trained, kind of. But not properly. The output is always
XOR 1 1 [smallest number]
XOR 0 0 [largest number]
XOR 1 0 [medium number]
XOR 0 1 [medium number]
I can never train the [1,1] [0,0] to be the same value.
If you have any suggestions, additional resources, articles, blogs, etc for me to look at I am very interested in learning more about this topic. Thank you for your assistance, I appreciate it greatly!
Ok. First of all. Backpropagation as it states work from back. From output through all hidden layers up to input layer. The error which is counted in last layer is "propagated" to all previous ones. So lets assume you have model of type: input - 1 hidden layer - output. In first step you count error from desired value and one you have. Then you do backprop on weights between hidden and output. And after that you do backprop for weights between input and hidden. In each step you backprop error from next to previous layer, simple. But maths can be confusing ;) Please take look at his short chapter for further explanation: http://page.mi.fu-berlin.de/rojas/neural/chapter/K7.pdf
I record a daily 2 minutes radio broadcast from Internet. There's always the same starting and ending jingle. Since the radio broadcast exact time may vary from more or less 6 minutes I have to record around 15 minutes of radio.
I wish to identify the exact time where those jingles are in the 15 minutes record, so I can extract the portion of audio I want.
I already started a C# application where I decode an MP3 to PCM data and convert the PCM data to a spectrogram based on http://www.codeproject.com/KB/audio-video/SoundCatcher.aspx
I tried to use a Cross Correlation algorithm on the PCM data but the algorithm is very slow around 6 minutes with a step of 10ms and is some occasion it fail to find the jingle start time.
Any ideas of algorithms to compare two spectrogram for match? Or a better way to find that jingle start time?
Thanks,
Update, sorry for the delay
First, thank for all the anwsers most of them were relevent and or interresting ideas.
I tried to implement the Shazam algorithm proposed by fonzo. But failed to detect the peaks in the spectrogram. Here's three spectrograms of the starting jingle from three different records. I tried AForge.NET with the blob filter (but it failed to identify peaks), to blur the image and check for difference in height, the Laplace convolution, slope analysis, to detect the series of vertical bars (but there was too many false positive)...
In the mean while, I tried the Hough algorithm proposed by Dave Aaron Smith. Where I calculate the RMS of each columns. Yes yes each columns, it's a O(N*M) but M << N (Notice a column is around 8k of sample). So in the overall it's not that bad, still the algorithm take about 3 minutes, but has never fail.
I could go with that solution, but if possible, I would prefer the Shazam cause it's O(N) and probably much faster (and cooler also). So does any of you have an idea of an algorithm to always detect the same points in those spectrograms (doesn't have to be peaks), thanks to add a comment.
New Update
Finally, I went with the algorithm explained above, I tried to implement the Shazam algorithm, but failed to find proper peaks in the spectrogram, the identified points where not constant from one sound file to another. In theory, the Shazam algorithm is the solution for that kind of problem. The Hough algorithm proposed by Dave Aaron Smith was more stable and effective. I split around 400 files, and only 20 of them fail to split properly. Disk space when from 8GB to 1GB.
Thanks, for your help.
There's a description of the algorithm used by the shazam service (which identifies a music given a short possibly noisy sample) here : http://www.ee.columbia.edu/~dpwe/papers/Wang03-shazam.pdf
From what I understood, the first thing done is to isolate peaks in the spectrogram (with some tweaks to assure an uniform coverage), which will give a "constellation" of pair of values (time;frequency) from the initial spectrogram. Once done, the sample constellation is compared to the constellation of the full track by translating a window of the sample length from the beginning to the end and counting the number of correlated points.
The paper then describes the technical solution they found to be able to do the comparison fast even with a huge collection of tracks.
I wonder if you could use a Hough transform. You would start by cataloging each step of the opening sequence. Let's say you use 10 ms steps and the opening sequence is 50 ms long. You compute some metric on each step and get
1 10 1 17 5
Now go through your audio and analyze each 10 ms step for the same metric. Call this array have_audio
8 10 8 7 5 1 10 1 17 6 2 10...
Now create a new empty array that's the same length as have_audio. Call it start_votes. It will contain "votes" for the start of the opening sequence. If you see a 1, you may be in the 1st or 3rd step of the opening sequence, so you have 1 vote for the opening sequence starting 1 step ago and 1 vote for the opening sequence starting 3 steps ago. If you see a 10, you have 1 vote for the opening sequence starting 2 steps ago, a 17 votes for 4 step ago, and so on.
So for that example have_audio, your votes will look like
2 0 0 1 0 4 0 0 0 0 0 1 ...
You have a lot of votes at position 6, so there's a good chance the opening sequence starts there.
You could improve performance by not bothering to analyze the entire opening sequence. If the opening sequence is 10 seconds long, you could just search for the first 5 seconds.
Here is a good python package that does just this:
https://code.google.com/p/py-astm/
If you are looking for a specific algorithm, good search terms to use are "accoustic fingerprinting" or "perceptual hashing".
Here's another python package that could also be used:
http://rudd-o.com/new-projects/python-audioprocessing/documentation/manuals/algorithms/butterscotch-signatures
If you already know the jingle sequence, you could analyse the correlation with the sequence instead of the cross correlation between the full 15 minutes tracks.
To quickly calculate the correlation against the (short) sequence, I would suggest using a Wiener filter.
Edit: a Wiener filter is a way to locate a signal in a sequence with noise. In this application, we are considering anything that is "not jingle" as noise (question for the reader: can we still assume that the noise is white and not correlated?).
( I found the reference I was looking for! The formulas I remembered were a little off and I'll remove them now)
The relevant page is Wiener deconvolution. The idea is that we can define a system whose impulse response h(t) has the same waveform as the jingle, and we have to locate the point in a noisy sequence where the system has received an impulse (i.e.: emitted a jingje).
Since the jingle is known, we can calculate its power spectrum H(f), and since we can assume that a single jingle appears in a recorded sequence, we can say that the unknown input x(t) has the shape of a pulse, whose power density S(f) is constant at each frequency.
Given the knowledges above, you can use the formula to obtain a "jingle-pass" filter (as in, only signals shaped like the jingle can pass) whose output is highest when the jingle is played.
My teacher asked me to create a program to solve something like:
2x plus 7y plus 2z = 76
6x plus 1y plus 4z = 26
8x plus 2y plus 18z = 1
x = ?
y = ?
z = ?
Problem is, this is literally the first two days of class and he expects us to make something like this.
Any help?
Since this is homework, I'll provide guidance, but not a complete answer...
My suggestion: Write this out on paper. How would you approach this on paper? Once you figure out the basic logic required, translating that into C# should be fairly straightforward.
You'll need to assign a variable for each portion of the equation (not just x/y/z, but also the coefficients), and just step through it in code using the same steps you do on paper.
If you know some maths, you can solve systems of equations using a matrix library (or roll your own).
I would suggest that you come up with the algorithm in pseudo-code before you touch any C#.
At least if you have defined the steps that you need to perform, the task simply becomes one of learning the syntax of C# to accomplish the steps.
Looks like you'll need a math textbook ;)
Have a go at solving this yourself on paper, but keep a note of what steps you do and try and work out what "Algorithm" you are using.
Once you've worked out your algorithm, have a go at writing some C# that does the same thing.
One more advice that can help you is that you'll need to store the equation in some data structure and then (repeatedly) run some steps that modify the data structure. The question is, which data structure can nicely represent this kind of data? If you focus just on the coefficients (since each row always has the same variable in it), you can write just:
2 7 2 76
6 1 4 26
8 2 18 1
Also, you can assume that all operations are + because "minus 7y" actually means "plus (-7)y". This looks like a 2D array, so when programming in C#, you can start by representing the equations as int[,]. Once you load the data into this data structure, you'll just need to write a method that does the operation you did on paper (in general).
Once you get the coefficients represented by a matrix (2 dimensional array), try googling "RREF" (Reduced Row Echelon Form). This is the matrix operation you will want to implement in your program in order to solve the system of equations. Good luck.