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
386 changes: 386 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,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "1.0">
<FileBreakpoints>
<FileBreakpoint
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "iDNA/AppDelegate.m"
timestampString = "381760698.614277"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "26"
endingLineNumber = "26"
landmarkName = "-applicationShouldTerminate:"
landmarkType = "5">
</FileBreakpoint>
</FileBreakpoints>
</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 = "FA43D70016AFDFBD00CDECCF"
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 = "FA43D70016AFDFBD00CDECCF"
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 = "FA43D70016AFDFBD00CDECCF"
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 = "FA43D70016AFDFBD00CDECCF"
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>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>FA43D70016AFDFBD00CDECCF</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
Binary file added iDNA/iDNA/.DS_Store
Binary file not shown.
47 changes: 47 additions & 0 deletions iDNA/iDNA/AppDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// AppDelegate.h
// iDNA
//
// Created by alex on 17/12/2012.
// Copyright (c) 2012 alex. All rights reserved.
//

#import <Cocoa/Cocoa.h>

@class Cell;
@class PreferencesController;
@class RandomWindowController;

@interface AppDelegate : NSObject <NSApplicationDelegate> {
PreferencesController *preferences;
RandomWindowController *randomPanel;

NSInteger populationSize;
NSInteger DNALength;
NSInteger mutationRate;
BOOL paused;
}

@property Cell* DNA; // goal DNA

@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSWindow *randomPanel;
@property (weak) IBOutlet NSTextField *populationSizeTextField;
@property (weak) IBOutlet NSTextField *DNALengthTextField;
@property (weak) IBOutlet NSTextField *mutationRateTextField;
@property (weak) IBOutlet NSTextField *goalDNATextField;
@property (weak) IBOutlet NSTextField *generationLabel;
@property (weak) IBOutlet NSTextField *bestMatchLabel;
@property (weak) IBOutlet NSButton *startEvolutionButton;
@property (weak) IBOutlet NSButton *pauseButton;
@property (weak) IBOutlet NSSlider *populationSizeSlider;
@property (weak) IBOutlet NSSlider *DNALengthSlider;
@property (weak) IBOutlet NSSlider *mutationRateSlider;
@property (weak) IBOutlet NSButton *loadDNAButton;

- (IBAction)startEvolution:(id)sender;
- (IBAction)pauseClick:(id)sender;
- (IBAction)saveAs:(id)sender;
- (IBAction)openFile:(id)sender;

@end
184 changes: 184 additions & 0 deletions iDNA/iDNA/AppDelegate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
//
// AppDelegate.m
// iDNA
//
// Created by alex on 17/12/2012.
// Copyright (c) 2012 alex. All rights reserved.
//

#import "AppDelegate.h"
#import "Cell.h"
#import "Population.h"
#import "PreferencesController.h"
#import "RandomWindowController.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[self setValue:[NSNumber numberWithLong:[preferences populationSize]] forKey:@"populationSize"];
[self setValue:[NSNumber numberWithLong:[preferences DNALength]] forKey:@"DNALength"];
[self setValue:[NSNumber numberWithLong:[preferences mutationRate]] forKey:@"mutationRate"];
}

-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"MSG_EXIT", @"") defaultButton:NSLocalizedString(@"BTN_YES", @"")alternateButton:NSLocalizedString(@"BTN_NO", @"") otherButton:nil informativeTextWithFormat:@""];

NSInteger answer = [alert runModal];

if (answer == NSAlertAlternateReturn) return NSTerminateCancel;

return NSTerminateNow;
}

-(id)init {
if (self = [super init]) {
preferences = [[PreferencesController alloc] init];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDNAChange:) name:DNAChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleFinishRandomGeneration:) name:@"FinishRandomGeneration" object:nil];

_DNA = [[Cell alloc] init];
[self addObserver:self forKeyPath:@"populationSize" options:0 context:nil];
[self addObserver:self forKeyPath:@"DNALength" options:0 context:nil];
[self addObserver:self forKeyPath:@"mutationRate" options:0 context:nil];

paused = NO;
}

return self;
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"populationSize"]) {
[preferences setPopulationSize:[[self valueForKey:@"populationSize"] intValue]];
} else if ([keyPath isEqualToString:@"DNALength"]) {
[_DNA populateForSize:[[self valueForKey:@"DNALength"] intValue]];
[preferences setDNALength:[[self valueForKey:@"DNALength"] intValue]];
} else if ([keyPath isEqualToString:@"mutationRate"]) {
[preferences setMutationRate:[[self valueForKey:@"mutationRate"] intValue]];
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}

-(void)handleDNAChange:(NSNotification *)n
{
[_goalDNATextField setStringValue:[_DNA asString]];
}

- (IBAction)startEvolution:(id)sender
{
randomPanel = [[RandomWindowController alloc] initWithWindowNibName:@"RandomWindowController"];

[NSApp beginSheet: [randomPanel window]
modalForWindow: [self window]
modalDelegate: randomPanel
didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
contextInfo: nil];

[NSApp runModalForWindow: [randomPanel window]];
[NSApp endSheet: [randomPanel window]];
}

-(void)handleFinishRandomGeneration:(NSNotification*)notification
{
NSLog(@"finish random generation");

NSNumber *number = [[notification userInfo] objectForKey: @"random"];

// абсолютно ненужное действие, но требуется по условиям задания
srandom(number);

[self setStateOfUIElements:FALSE];
[self performSelectorInBackground:@selector(evolutionJob) withObject:nil];
}

-(void)evolutionJob
{
Population *population = [[Population alloc] initPopulationWithSize:[[self valueForKey:@"populationSize"] intValue] andSizeDNA:[[self valueForKey:@"DNALength"] intValue] andGoalDNA:_DNA];

int i = 1;
int evolutionResult = -1;
int bestMatch = 999;
int l = [[self valueForKey:@"DNALength"] intValue];
paused = NO;

while (true) {
[_generationLabel setStringValue:[NSString stringWithFormat:NSLocalizedString(@"GENERATION", ""), i]];

evolutionResult = [population evolution:[[self valueForKey:@"mutationRate"] intValue]];
if (bestMatch > evolutionResult) {
bestMatch = evolutionResult;
[_bestMatchLabel setStringValue:[NSString stringWithFormat:NSLocalizedString(@"BEST_MATCH", ""), 100-bestMatch*100/l]];
}

// для отладки
/*
[_goalDNATextField setStringValue:[[_DNA asString] stringByAppendingFormat:@"\r\n%@ - %d (%d)", [[population bestMatch] asString], [[population bestMatch] hammingDistance:_DNA], evolutionResult]];
*/

if (paused || !bestMatch) {
[self setStateOfUIElements:TRUE];
break;
}

i++;
}
}

-(void)setStateOfUIElements:(BOOL)newState
{
[_pauseButton setEnabled:!newState];
[_startEvolutionButton setEnabled:newState];
[_populationSizeSlider setEnabled:newState];
[_populationSizeTextField setEnabled:newState];
[_DNALengthSlider setEnabled:newState];
[_DNALengthTextField setEnabled:newState];
[_mutationRateSlider setEnabled:newState];
[_mutationRateTextField setEnabled:newState];
[_loadDNAButton setEnabled:newState];
}

- (IBAction)pauseClick:(id)sender
{
paused = YES;
}

- (IBAction)saveAs:(id)sender
{
NSSavePanel *panel = [NSSavePanel savePanel];
if ([panel runModal] == NSOKButton) {
NSError *error;

[[[self DNA] asString] writeToURL:[panel URL] atomically:YES encoding:NSUTF8StringEncoding error:&error];

if (error.code) {
NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"ERROR_SAVE", @"") defaultButton:NSLocalizedString(@"BTN_CLOSE", @"") alternateButton:nil otherButton:nil informativeTextWithFormat:@""];
[alert runModal];
}
}
}

- (IBAction)openFile:(id)sender
{
NSOpenPanel *panel = [NSOpenPanel openPanel];
if ([panel runModal] == NSOKButton) {
NSError *error;

NSString *string = [NSString stringWithContentsOfURL:[panel URL] encoding:NSUTF8StringEncoding error:&error];
// ставим правильное значение длины ДНК
[self setValue:[NSNumber numberWithInt:(int)string.length] forKey:@"DNALength"];
// пишем новое ДНК в соотв. поле
[_DNA populateWithString:string];

if (error.code) {
NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"ERROR_OPEN", @"") defaultButton:NSLocalizedString(@"BTN_CLOSE", @"") alternateButton:nil otherButton:nil informativeTextWithFormat:@""];
[alert runModal];
}
}
}

@end
Loading