Skip to content
This repository was archived by the owner on Feb 2, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
353 changes: 353 additions & 0 deletions iDNA/iDNA.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "1.0">
</Bucket>
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0450"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00AF4DA9168743A400A45A83"
BuildableName = "iDNA.app"
BlueprintName = "iDNA"
ReferencedContainer = "container:iDNA.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00AF4DA9168743A400A45A83"
BuildableName = "iDNA.app"
BlueprintName = "iDNA"
ReferencedContainer = "container:iDNA.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00AF4DA9168743A400A45A83"
BuildableName = "iDNA.app"
BlueprintName = "iDNA"
ReferencedContainer = "container:iDNA.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00AF4DA9168743A400A45A83"
BuildableName = "iDNA.app"
BlueprintName = "iDNA"
ReferencedContainer = "container:iDNA.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>iDNA.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>00AF4DA9168743A400A45A83</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
24 changes: 24 additions & 0 deletions iDNA/iDNA/AppDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#import <Cocoa/Cocoa.h>
#import "EvolutionProgressDelegate.h"
@class Evolution;

@interface AppDelegate : NSObject <NSApplicationDelegate, EvolutionProgressDelegate, NSWindowDelegate> {
Evolution *evolution;
IBOutlet NSTextField *generationLabel;
IBOutlet NSTextField *bestMatchLabel;
IBOutlet NSLevelIndicator *progressIndicator;
}

@property (assign) IBOutlet NSWindow *window;
@property Evolution *evolution;
@property (readonly) BOOL canChangeParams;
@property (readonly) NSString *startStopButtonTitle;
@property (readonly) NSString *pauseResumeButtonTitle;
@property (readonly) BOOL pauseResumeButtonIsEnabled;

-(IBAction)startStopEvolution:(id)sender;
-(IBAction)pauseResumeEvolution:(id)sender;

-(IBAction)loadGoalDNAFromFile:(id)sender;

@end
166 changes: 166 additions & 0 deletions iDNA/iDNA/AppDelegate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#import "AppDelegate.h"
#import "Evolution.h"

@implementation AppDelegate

@synthesize evolution;

-(id)init {
self = [super init];
if (self) {
[[self class] registerDefaultSettings];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
evolution = [[Evolution alloc] init];
[evolution setDelegate:self];
for (NSString *evolutionParam in @[ @"populationSize", @"dnaLength", @"mutationRate" ]) {
[evolution setValue:[defaults objectForKey:evolutionParam] forKey:evolutionParam];
[evolution addObserver:self forKeyPath:evolutionParam options:NSKeyValueObservingOptionNew context:nil];
}
}
return self;
}

+(void)registerDefaultSettings {
NSDictionary *defaultSettings = @{
@"populationSize": @100,
@"dnaLength": @20,
@"mutationRate": @10
};
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultSettings];
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (object != evolution) {
return;
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:change[@"new"] forKey:keyPath];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[self.window setDelegate:self];
}

-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
return YES;
}

-(BOOL)windowShouldClose:(id)sender {
NSAlert *alertWindow = [NSAlert alertWithMessageText:NSLocalizedString(@"QUIT_MSG", "Quit iDNA")
defaultButton:NSLocalizedString(@"YES", @"Yes")
alternateButton:NSLocalizedString(@"NO", @"No")
otherButton:nil
informativeTextWithFormat:NSLocalizedString(@"QUIT_TEXT", @"Do you really want to exit?")];
if ([alertWindow runModal] == NSAlertDefaultReturn) {
return YES;
}
return NO;
}

-(IBAction)startStopEvolution:(id)sender {
[self willChangeState];
if (evolution.inProgress) {
[evolution stop];
} else {
[evolution start];
}
[self didChangeState];
}

-(IBAction)pauseResumeEvolution:(id)sender {
[self willChangeState];
if (evolution.paused) {
[evolution resume];
} else {
[evolution pause];
}
[self didChangeState];
}

-(void)willChangeState {
[self willChangeValueForKey:@"canChangeParams"];
[self willChangeValueForKey:@"startStopButtonTitle"];
[self willChangeValueForKey:@"pauseResumeButtonTitle"];
[self willChangeValueForKey:@"pauseResumeButtonIsEnabled"];
}

-(void)didChangeState {
[self didChangeValueForKey:@"canChangeParams"];
[self didChangeValueForKey:@"startStopButtonTitle"];
[self didChangeValueForKey:@"pauseResumeButtonTitle"];
[self didChangeValueForKey:@"pauseResumeButtonIsEnabled"];
}

-(BOOL)canChangeParams {
return evolution.inProgress == NO;
}

-(NSString *)startStopButtonTitle {
return evolution.inProgress ? NSLocalizedString(@"STOP", @"Stop evolution") : NSLocalizedString(@"START", @"Start evolution");
}

-(NSString *)pauseResumeButtonTitle {
return evolution.paused ? NSLocalizedString(@"RESUME", @"Resume") : NSLocalizedString(@"PAUSE", @"Pause");
}

-(BOOL)pauseResumeButtonIsEnabled {
return evolution.inProgress == YES;
}

-(void)evolutionStateHasChanged:(NSNotification *)notification {
NSDictionary *userInfo = notification.userInfo;
[generationLabel setStringValue:[NSString stringWithFormat:@"%@", [userInfo objectForKey:@"generation"]]];
NSNumber *bestMatch = [userInfo objectForKey:@"bestMatch"];
[bestMatchLabel setStringValue:[NSString stringWithFormat:@"%@%%", bestMatch]];
[progressIndicator setDoubleValue: [bestMatch doubleValue]];
}

-(void)evolutionGoalIsReached {
[self willChangeState];
[self didChangeState];
}

-(IBAction)loadGoalDNAFromFile:(id)sender {
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
if (![openPanel runModal] == NSFileHandlingPanelOKButton) {
return;
}

NSString *errorText = nil;
NSString *dnaString = [NSString stringWithContentsOfURL:[openPanel URL] usedEncoding:nil error:nil];
NSPredicate *dnaStringPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"[ATGC]+"];

if (dnaString == nil) {
errorText = NSLocalizedString(@"FILE_READ_ERROR", @"Cannot read the file");
} else if (![dnaStringPredicate evaluateWithObject:dnaString]) {
errorText = NSLocalizedString(@"FILE_FORMAT_ERROR", @"Text from the file is not DNA");
} else if ([dnaString length] < 4) {
errorText = NSLocalizedString(@"TOO_SHORT_DNA_ERROR", @"DNA is too short");
} else if ([dnaString length] > 100) {
errorText = NSLocalizedString(@"TOO_LONG_DNA_ERROR", @"DNA is too long");
}

if (errorText) {
[self showAlertWithMessageText:@"Ops" informativeText:errorText];
return;
}

NSAlert *alertWindow = [NSAlert alertWithMessageText:NSLocalizedString(@"OPEN_FILE_MSG", @"Open file")
defaultButton:NSLocalizedString(@"YES", @"Yes")
alternateButton:NSLocalizedString(@"NO", @"No")
otherButton:nil
informativeTextWithFormat:NSLocalizedString(@"REPLACE_TEXT", @"Do you really want replace current goal DNA with DNA from file?")];
if ([alertWindow runModal] != NSAlertDefaultReturn) {
return;
}

[evolution loadGoalDNA:dnaString];
}

-(void)showAlertWithMessageText:(NSString *)text informativeText:(NSString *)informativeText {
NSAlert *alert = [NSAlert alertWithMessageText:text defaultButton:nil alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", informativeText];
[alert runModal];
}

@end
13 changes: 13 additions & 0 deletions iDNA/iDNA/Cell.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#import <Foundation/Foundation.h>

@interface Cell : NSObject

@property NSMutableArray* dna;

-(id) initWithRandomDNAOfLength:(NSInteger)length;
-(id) initWithDNA:(NSMutableArray *)dna;
-(int) hammingDistance:(Cell*)otherCell;
-(void) mutate:(NSInteger)percent;
-(NSString *) nucleobaseAtIndex:(NSInteger)index;

@end
Loading